Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve E2 Constants #2846

Merged
merged 2 commits into from
Nov 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 65 additions & 0 deletions lua/entities/gmod_wire_expression2/base/compiler.lua
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
AddCSLuaFile()

local Warning, Error = E2Lib.Debug.Warning, E2Lib.Debug.Error
local Token, TokenVariant = E2Lib.Tokenizer.Token, E2Lib.Tokenizer.Variant
local Node, NodeVariant = E2Lib.Parser.Node, E2Lib.Parser.Variant
local Operator = E2Lib.Operator

Expand Down Expand Up @@ -1211,6 +1212,70 @@ local CompileVisitors = {
end, var.type
end,

---@param data Token<string>
[NodeVariant.ExprConstant] = function (self, trace, data, used_as_stmt)
local value = self:Assert( wire_expression2_constants[data.value], "Invalid constant: " .. data.value, trace ).value

local ty = type(value)
if ty == "number" then
return self:CompileExpr( Node.new(NodeVariant.ExprLiteral, { "n", value }, trace) )
elseif ty == "string" then
return self:CompileExpr( Node.new(NodeVariant.ExprLiteral, { "s", value }, trace) )
elseif ty == "Vector" and wire_expression2_funcs["vec(nnn)"] then
return self:CompileExpr(Node.new(NodeVariant.ExprCall, {
Token.new(TokenVariant.String, "vec"),
{
Node.new(NodeVariant.ExprLiteral, { "n", value[1] }, trace),
Node.new(NodeVariant.ExprLiteral, { "n", value[2] }, trace),
Node.new(NodeVariant.ExprLiteral, { "n", value[3] }, trace)
}
}, trace))
elseif ty == "Angle" and wire_expression2_funcs["ang(nnn)"] then
return self:CompileExpr(Node.new(NodeVariant.ExprCall, {
Token.new(TokenVariant.String, "ang"),
{
Node.new(NodeVariant.ExprLiteral, { "n", value[1] }, trace),
Node.new(NodeVariant.ExprLiteral, { "n", value[2] }, trace),
Node.new(NodeVariant.ExprLiteral, { "n", value[3] }, trace)
}
}, trace))
elseif ty == "table" then -- Know it's an array already from registerConstant
local out = {}
for i, val in ipairs(value) do
local ty = type(val)
if ty == "number" then
out[i] = Node.new(NodeVariant.ExprLiteral, { "n", val }, trace)
elseif ty == "string" then
out[i] = Node.new(NodeVariant.ExprLiteral, { "s", val }, trace)
elseif ty == "Vector" then
out[i] = Node.new(NodeVariant.ExprCall, {
Token.new(TokenVariant.String, "vec"),
{
Node.new(NodeVariant.ExprLiteral, { "n", val[1] }, trace),
Node.new(NodeVariant.ExprLiteral, { "n", val[2] }, trace),
Node.new(NodeVariant.ExprLiteral, { "n", val[3] }, trace)
}
}, trace)
elseif ty == "Angle" then
out[i] = Node.new(NodeVariant.ExprCall, {
Token.new(TokenVariant.String, "ang"),
{
Node.new(NodeVariant.ExprLiteral, { "n", val[1] }, trace),
Node.new(NodeVariant.ExprLiteral, { "n", val[2] }, trace),
Node.new(NodeVariant.ExprLiteral, { "n", val[3] }, trace)
}
}, trace)
else
self:Error("Constant " .. data.value .. " has invalid data type", trace)
end
end

return self:CompileExpr( Node.new(NodeVariant.ExprArray, out, trace) )
else
self:Error("Constant " .. data.value .. " has invalid data type", trace)
end
end,

---@param data Node[]|{ [1]: Node, [2]:Node }[]
[NodeVariant.ExprArray] = function (self, trace, data)
if #data == 0 then
Expand Down
8 changes: 7 additions & 1 deletion lua/entities/gmod_wire_expression2/base/parser.lua
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,8 @@ local NodeVariant = {
ExprTable = 35, -- `table(1, 2, 3)` or `table(1 = 2, "test" = 3)`
ExprFunction = 36, -- `function() {}`
ExprLiteral = 37, -- `"test"` `5e2` `4.023` `4j`
ExprIdent = 38 -- `Variable`
ExprIdent = 38, -- `Variable`
ExprConstant = 39, -- `_FOO`
}

Parser.Variant = NodeVariant
Expand Down Expand Up @@ -1002,6 +1003,11 @@ function Parser:Expr15()
return Node.new(NodeVariant.ExprIdent, ident, ident.trace)
end

local constant = self:Consume(TokenVariant.Constant)
if constant then
return Node.new(NodeVariant.ExprConstant, constant, constant.trace)
end

-- Error Messages
if self:Eof() then
self:Error("Further input required at end of code, incomplete expression")
Expand Down
11 changes: 1 addition & 10 deletions lua/entities/gmod_wire_expression2/base/tokenizer.lua
Original file line number Diff line number Diff line change
Expand Up @@ -276,16 +276,7 @@ function Tokenizer:Next()

match = self:ConsumePattern("^_[A-Z0-9_]+")
if match then
-- Constant value
local value = wire_expression2_constants[match]

if type(value) == "number" then
return Token.new(TokenVariant.Decimal, value)
elseif type(value) == "string" then
return Token.new(TokenVariant.String, value)
else
return self:Error("Constant (" .. match .. ") has invalid data type (" .. type(value) .. ")")
end
return Token.new(TokenVariant.Constant, match)
end

if self:ConsumePattern("^_") then
Expand Down
39 changes: 36 additions & 3 deletions lua/entities/gmod_wire_expression2/core/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -174,13 +174,46 @@ function registerFunction(name, pars, rets, func, cost, argnames, attributes)
wire_expression2_funclist[name] = true
end

function E2Lib.registerConstant(name, value)
---@alias E2Constant string | number | E2Constant[]

local TypeMap = {
["number"] = "n", ["string"] = "s",
["Vector"] = "v", ["Angle"] = "a",
["table"] = "r"
}

local ValidArrayTypes = {
["number"] = true, ["string"] = true,
["Vector"] = true, ["Angle"] = true
}

---@param value E2Constant
---@param description string?
function E2Lib.registerConstant(name, value, description)
if name:sub(1, 1) ~= "_" then name = "_" .. name end

local ty = type(value)
assert(ty == "number" or ty == "string", "Invalid value passed to registerConstant (must be number or string)")
local e2ty = TypeMap[ty]

if e2ty then
if ty == "table" then -- ensure it's actually an array (sequential and valid types)
local i = 1
for _, val in pairs(value) do
assert(value[i] ~= nil, "Invalid array passed to registerConstant (must be sequential)")
assert(ValidArrayTypes[type(val)], "Invalid array passed to registerConstant (must only contain numbers, strings, vector or angles)")
i = i + 1
end
end

wire_expression2_constants[name] = value
wire_expression2_constants[name] = {
value = value,
type = e2ty,
description = description,
extension = E2Lib.currentextension
}
else
error("Invalid value passed to registerConstant. Only numbers, strings, vectors, angles and arrays can be constant values.")
end
end

--- Example:
Expand Down
3 changes: 3 additions & 0 deletions lua/entities/gmod_wire_expression2/core/vector.lua
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ registerType("vector", "v", Vector(0, 0, 0),
end
)

E2Lib.registerConstant("VECTOR_ORIGIN", Vector(0, 0, 0), "Origin of the map. This is vec(0, 0, 0)")
E2Lib.registerConstant("VECTOR_UP", Vector(0, 0, 1), "Upward direction. This is vec(0, 0, 1)")

--------------------------------------------------------------------------------

__e2setcost(1) -- approximated
Expand Down
23 changes: 13 additions & 10 deletions lua/wire/client/e2helper.lua
Original file line number Diff line number Diff line change
Expand Up @@ -152,12 +152,17 @@ function E2Helper.Create(reset)
self:ClearSelection()
self:SelectItem(line)

-- don't try describing the function when it is actually a constant
if E2Helper.constants[line] then
E2Helper.FuncEntry:SetText("Constant value")
local const = E2Helper.constants[line]
if const then
E2Helper.FuncEntry:SetText(line:GetValue(1) .. " (" .. const.type .. ")")

E2Helper.DescriptionEntry:SetText("Constants do not support descriptions (yet)")
E2Helper.DescriptionEntry:SetTextColor(Color(128, 128, 128))
if const.description then
E2Helper.DescriptionEntry:SetText(const.description)
E2Helper.DescriptionEntry:SetTextColor(Color(0, 0, 0))
else
E2Helper.DescriptionEntry:SetText("No description found :(")
E2Helper.DescriptionEntry:SetTextColor(Color(128, 128, 128))
end
else
E2Helper.FuncEntry:SetText(E2Helper.GetFunctionSyntax(line:GetValue(1), line:GetValue(3), line:GetValue(4)))
local desc = getdesc(line:GetValue(1), line:GetValue(3))
Expand Down Expand Up @@ -314,13 +319,11 @@ function E2Helper.Update()
E2Helper.constants = {}
if E2Helper.CurrentMode == true then
for k, v in pairs(wire_expression2_constants) do
local strType = isstring(v) and "s" or "n"

-- constants have no arguments and no cost
local name, args, rets, cost = k, nil, strType, 0
local name, args, rets, cost = k, nil, v.type, 0
if name:lower():find(search_name, 1, true) and search_args == "" and rets:lower():find(search_rets, 1, true) and string.find("constants",search_from, 1, true) then
local line = E2Helper.ResultFrame:AddLine(name, "constants", args, rets, cost)
E2Helper.constants[line] = true
local line = E2Helper.ResultFrame:AddLine(name, v.extension, args, rets, cost)
E2Helper.constants[line] = v
count = count + 1
if count >= maxcount then break end
end
Expand Down
2 changes: 1 addition & 1 deletion lua/wire/client/text_editor/modes/e2.lua
Original file line number Diff line number Diff line change
Expand Up @@ -551,7 +551,7 @@ function EDITOR:SyntaxColorLine(row)
-- eat next token
if self:NextPattern("^_[A-Z][A-Z_0-9]*") then
local word = self.tokendata
for k,_ in pairs( wire_expression2_constants ) do
for k in pairs( wire_expression2_constants ) do
if k == word then
tokenname = "constant"
end
Expand Down
2 changes: 1 addition & 1 deletion lua/wire/client/text_editor/texteditor.lua
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
local math_floor = math.floor
local math_Clamp = math.Clamp
local math_ceil = math.ceil
local string_match = string.match

Check warning on line 13 in lua/wire/client/text_editor/texteditor.lua

View workflow job for this annotation

GitHub Actions / lint

"Unused variable"

Unused variable: string_match
local string_gmatch = string.gmatch
local string_gsub = string.gsub
local string_rep = string.rep
Expand Down Expand Up @@ -243,7 +243,7 @@
prev_colors = color

if first_loop then
str = str .. string_format( '[color="#%x%x%x"]', color.r - 50, color.g - 50, color.b - 50 ) .. v[1]

Check warning on line 246 in lua/wire/client/text_editor/texteditor.lua

View workflow job for this annotation

GitHub Actions / lint

"Syntax inconsistency"

Inconsistent use of 'single quoted strings' and 'double quoted strings'
first_loop = false
else
str = str .. string_format( '[/color][color="#%x%x%x"]', color.r - 50, color.g - 50, color.b - 50 ) .. v[1]
Expand All @@ -251,7 +251,7 @@
end
end

str = str .. "\r\n"

Check warning on line 254 in lua/wire/client/text_editor/texteditor.lua

View workflow job for this annotation

GitHub Actions / lint

"Syntax inconsistency"

Inconsistent use of 'double quoted strings' and 'single quoted strings'

end

Expand Down Expand Up @@ -349,7 +349,7 @@
end

function EDITOR:GetValue()
return (string_gsub(table_concat(self.Rows, "\n"), "\r", ""))

Check warning on line 352 in lua/wire/client/text_editor/texteditor.lua

View workflow job for this annotation

GitHub Actions / lint

"Unnecessary parentheses"

Unnecessary parentheses
end

function EDITOR:HighlightLine( line, r, g, b, a )
Expand Down Expand Up @@ -693,7 +693,7 @@
if offset > 0 then
local numRows = #self.Rows
while true do
local length = #(self.Rows[row]) - col + 2

Check warning on line 696 in lua/wire/client/text_editor/texteditor.lua

View workflow job for this annotation

GitHub Actions / lint

"Unnecessary parentheses"

Unnecessary parentheses
if offset < length then
col = col + offset
break
Expand All @@ -719,7 +719,7 @@
else
offset = offset - col
row = row - 1
col = #(self.Rows[row]) + 1

Check warning on line 722 in lua/wire/client/text_editor/texteditor.lua

View workflow job for this annotation

GitHub Actions / lint

"Unnecessary parentheses"

Unnecessary parentheses
end
end
end
Expand Down Expand Up @@ -896,14 +896,14 @@
if text == "" then return end
if not ctrlv then
if text == "\n" or text == "`" then return end
if text == "}" and GetConVarNumber('wire_expression2_autoindent') ~= 0 then

Check warning on line 899 in lua/wire/client/text_editor/texteditor.lua

View workflow job for this annotation

GitHub Actions / lint

"Deprecated"

Deprecated: Use ConVar objects instead

Check warning on line 899 in lua/wire/client/text_editor/texteditor.lua

View workflow job for this annotation

GitHub Actions / lint

"Syntax inconsistency"

Inconsistent use of 'single quoted strings' and 'double quoted strings'
local row = self.Rows[self.Caret[1]]
self:SetSelection(text)
if string.match(row,"[^%s]") == nil then
local caret = self:Selection()[1]
self:Indent(true)
self.Caret = caret
self.Caret[2] = #(self.Rows[caret[1]]) + 1

Check warning on line 906 in lua/wire/client/text_editor/texteditor.lua

View workflow job for this annotation

GitHub Actions / lint

"Unnecessary parentheses"

Unnecessary parentheses
self.Start[2] = self.Caret[2]
end
return
Expand Down Expand Up @@ -1218,7 +1218,7 @@

local use_patterns = vgui.Create( "DCheckBoxLabel", common_panel )
use_patterns:SetText( "Use Patterns" )
use_patterns:SetToolTip( "Use/Don't use Lua patterns in the find." )

Check warning on line 1221 in lua/wire/client/text_editor/texteditor.lua

View workflow job for this annotation

GitHub Actions / lint

"Deprecated"

Deprecated: Use :SetTooltip instead, notice the lowercase fucking t
use_patterns:SizeToContents()
use_patterns:SetConVar( "wire_expression2_editor_find_use_patterns" )
use_patterns:SetPos( 4, 4 )
Expand Down Expand Up @@ -2122,7 +2122,7 @@

local suggestions = {}

for name, _ in pairs( wire_expression2_constants ) do
for name in pairs( wire_expression2_constants ) do
if name:sub(1,len) == wordu then
count = count + 1
suggestions[count] = GetTableForConstant( name )
Expand Down
Loading