formatting

This commit is contained in:
Michael Freno
2025-12-07 08:46:39 -05:00
parent 5ef00fe65e
commit 4f60e00b2e

View File

@@ -30,46 +30,46 @@ local function tokenize(expr)
local tokens = {} local tokens = {}
local i = 1 local i = 1
local len = #expr local len = #expr
while i <= len do while i <= len do
local char = expr:sub(i, i) local char = expr:sub(i, i)
-- Skip whitespace -- Skip whitespace
if char:match("%s") then if char:match("%s") then
i = i + 1 i = i + 1
-- Number (including decimals, but NOT negative - handled separately below) -- Number (including decimals, but NOT negative - handled separately below)
elseif char:match("%d") or (char == "." and expr:sub(i + 1, i + 1):match("%d")) then elseif char:match("%d") or (char == "." and expr:sub(i + 1, i + 1):match("%d")) then
local numStr = "" local numStr = ""
-- Parse integer and decimal parts -- Parse integer and decimal parts
while i <= len and (expr:sub(i, i):match("%d") or expr:sub(i, i) == ".") do while i <= len and (expr:sub(i, i):match("%d") or expr:sub(i, i) == ".") do
numStr = numStr .. expr:sub(i, i) numStr = numStr .. expr:sub(i, i)
i = i + 1 i = i + 1
end end
local num = tonumber(numStr) local num = tonumber(numStr)
if not num then if not num then
return nil, "Invalid number: " .. numStr return nil, "Invalid number: " .. numStr
end end
-- Check for unit following the number -- Check for unit following the number
local unitStr = "" local unitStr = ""
while i <= len and expr:sub(i, i):match("[%a%%]") do while i <= len and expr:sub(i, i):match("[%a%%]") do
unitStr = unitStr .. expr:sub(i, i) unitStr = unitStr .. expr:sub(i, i)
i = i + 1 i = i + 1
end end
-- Default to px if no unit -- Default to px if no unit
if unitStr == "" then if unitStr == "" then
unitStr = "px" unitStr = "px"
end end
-- Validate unit -- Validate unit
local validUnits = { px = true, ["%"] = true, vw = true, vh = true, ew = true, eh = true } local validUnits = { px = true, ["%"] = true, vw = true, vh = true, ew = true, eh = true }
if not validUnits[unitStr] then if not validUnits[unitStr] then
return nil, "Invalid unit: " .. unitStr return nil, "Invalid unit: " .. unitStr
end end
table.insert(tokens, { table.insert(tokens, {
type = TokenType.NUMBER, type = TokenType.NUMBER,
value = num, value = num,
@@ -83,42 +83,47 @@ local function tokenize(expr)
-- Check if this is a negative number or subtraction -- Check if this is a negative number or subtraction
-- It's a negative number if previous token is an operator or opening paren -- It's a negative number if previous token is an operator or opening paren
local prevToken = tokens[#tokens] local prevToken = tokens[#tokens]
if not prevToken or prevToken.type == TokenType.PLUS or prevToken.type == TokenType.MINUS if
or prevToken.type == TokenType.MULTIPLY or prevToken.type == TokenType.DIVIDE not prevToken
or prevToken.type == TokenType.LPAREN then or prevToken.type == TokenType.PLUS
or prevToken.type == TokenType.MINUS
or prevToken.type == TokenType.MULTIPLY
or prevToken.type == TokenType.DIVIDE
or prevToken.type == TokenType.LPAREN
then
-- This is a negative number, continue to number parsing -- This is a negative number, continue to number parsing
local numStr = "-" local numStr = "-"
i = i + 1 i = i + 1
-- Parse integer and decimal parts -- Parse integer and decimal parts
while i <= len and (expr:sub(i, i):match("%d") or expr:sub(i, i) == ".") do while i <= len and (expr:sub(i, i):match("%d") or expr:sub(i, i) == ".") do
numStr = numStr .. expr:sub(i, i) numStr = numStr .. expr:sub(i, i)
i = i + 1 i = i + 1
end end
local num = tonumber(numStr) local num = tonumber(numStr)
if not num then if not num then
return nil, "Invalid number: " .. numStr return nil, "Invalid number: " .. numStr
end end
-- Check for unit following the number -- Check for unit following the number
local unitStr = "" local unitStr = ""
while i <= len and expr:sub(i, i):match("[%a%%]") do while i <= len and expr:sub(i, i):match("[%a%%]") do
unitStr = unitStr .. expr:sub(i, i) unitStr = unitStr .. expr:sub(i, i)
i = i + 1 i = i + 1
end end
-- Default to px if no unit -- Default to px if no unit
if unitStr == "" then if unitStr == "" then
unitStr = "px" unitStr = "px"
end end
-- Validate unit -- Validate unit
local validUnits = { px = true, ["%"] = true, vw = true, vh = true, ew = true, eh = true } local validUnits = { px = true, ["%"] = true, vw = true, vh = true, ew = true, eh = true }
if not validUnits[unitStr] then if not validUnits[unitStr] then
return nil, "Invalid unit: " .. unitStr return nil, "Invalid unit: " .. unitStr
end end
table.insert(tokens, { table.insert(tokens, {
type = TokenType.NUMBER, type = TokenType.NUMBER,
value = num, value = num,
@@ -145,7 +150,7 @@ local function tokenize(expr)
return nil, "Unexpected character: " .. char return nil, "Unexpected character: " .. char
end end
end end
table.insert(tokens, { type = TokenType.EOF }) table.insert(tokens, { type = TokenType.EOF })
return tokens return tokens
end end
@@ -182,7 +187,7 @@ end
---@return table ast Abstract syntax tree node ---@return table ast Abstract syntax tree node
function Parser:parseExpression() function Parser:parseExpression()
local left = self:parseTerm() local left = self:parseTerm()
while self:current().type == TokenType.PLUS or self:current().type == TokenType.MINUS do while self:current().type == TokenType.PLUS or self:current().type == TokenType.MINUS do
local op = self:current().type local op = self:current().type
self:advance() self:advance()
@@ -193,7 +198,7 @@ function Parser:parseExpression()
right = right, right = right,
} }
end end
return left return left
end end
@@ -201,7 +206,7 @@ end
---@return table ast Abstract syntax tree node ---@return table ast Abstract syntax tree node
function Parser:parseTerm() function Parser:parseTerm()
local left = self:parseFactor() local left = self:parseFactor()
while self:current().type == TokenType.MULTIPLY or self:current().type == TokenType.DIVIDE do while self:current().type == TokenType.MULTIPLY or self:current().type == TokenType.DIVIDE do
local op = self:current().type local op = self:current().type
self:advance() self:advance()
@@ -212,7 +217,7 @@ function Parser:parseTerm()
right = right, right = right,
} }
end end
return left return left
end end
@@ -220,7 +225,7 @@ end
---@return table ast Abstract syntax tree node ---@return table ast Abstract syntax tree node
function Parser:parseFactor() function Parser:parseFactor()
local token = self:current() local token = self:current()
if token.type == TokenType.NUMBER then if token.type == TokenType.NUMBER then
self:advance() self:advance()
return { return {
@@ -273,13 +278,13 @@ function Calc.new(expr)
_error = err, _error = err,
} }
end end
-- Parse -- Parse
local parser = Parser.new(tokens) local parser = Parser.new(tokens)
local success, ast = pcall(function() local success, ast = pcall(function()
return parser:parse() return parser:parse()
end) end)
if not success then if not success then
if Calc._ErrorHandler then if Calc._ErrorHandler then
Calc._ErrorHandler:warn("Calc", "VAL_006", { Calc._ErrorHandler:warn("Calc", "VAL_006", {
@@ -295,7 +300,7 @@ function Calc.new(expr)
_error = ast, _error = ast,
} }
end end
return { return {
_isCalc = true, _isCalc = true,
_expr = expr, _expr = expr,
@@ -323,7 +328,7 @@ function Calc.resolve(calcObj, viewportWidth, viewportHeight, parentSize, elemen
-- Error during parsing, return 0 -- Error during parsing, return 0
return 0 return 0
end end
--- Evaluate AST node recursively --- Evaluate AST node recursively
---@param node table AST node ---@param node table AST node
---@return number value Evaluated value in pixels ---@return number value Evaluated value in pixels
@@ -332,7 +337,7 @@ function Calc.resolve(calcObj, viewportWidth, viewportHeight, parentSize, elemen
-- Convert unit to pixels -- Convert unit to pixels
local value = node.value local value = node.value
local unit = node.unit local unit = node.unit
if unit == "px" then if unit == "px" then
return value return value
elseif unit == "%" then elseif unit == "%" then
@@ -397,7 +402,7 @@ function Calc.resolve(calcObj, viewportWidth, viewportHeight, parentSize, elemen
return 0 return 0
end end
end end
return evaluate(calcObj._ast) return evaluate(calcObj._ast)
end end