Quick Math Calculator

A dockable calculator. Type math or Luau expressions and get instant results.

Enter - to save to history
Left Click - Insert variable into input
Right Click - delete from history
Support My Work
If you liked my work and want to donate to me you can do so here
SourceCode
--!strict
local characterTypes = {
a = "Alphabet", b = "Alphabet", c = "Alphabet", d = "Alphabet", e = "Alphabet", f = "Alphabet", g = "Alphabet", h = "Alphabet", i = "Alphabet", j = "Alphabet", k = "Alphabet", l = "Alphabet", m = "Alphabet",
n = "Alphabet", o = "Alphabet", p = "Alphabet", q = "Alphabet", r = "Alphabet", s = "Alphabet", t = "Alphabet", u = "Alphabet", v = "Alphabet", w = "Alphabet", x = "Alphabet", y = "Alphabet", z = "Alphabet",
A = "Alphabet", B = "Alphabet", C = "Alphabet", D = "Alphabet", E = "Alphabet", F = "Alphabet", G = "Alphabet", H = "Alphabet", I = "Alphabet", J = "Alphabet", K = "Alphabet", L = "Alphabet", M = "Alphabet",
N = "Alphabet", O = "Alphabet", P = "Alphabet", Q = "Alphabet", R = "Alphabet", S = "Alphabet", T = "Alphabet", U = "Alphabet", V = "Alphabet", W = "Alphabet", X = "Alphabet", Y = "Alphabet", Z = "Alphabet",
_ = "Alphabet", ["0"] = "Digit", ["1"] = "Digit", ["2"] = "Digit", ["3"] = "Digit", ["4"] = "Digit", ["5"] = "Digit", ["6"] = "Digit", ["7"] = "Digit", ["8"] = "Digit", ["9"] = "Digit",
}
local map = {
-- math
abs="math.abs", acos="math.acos", asin="math.asin", atan="math.atan", atan2="math.atan2",
ceil="math.ceil", clamp="math.clamp", cos="math.cos", cosh="math.cosh", deg="math.deg",
exp="math.exp", floor="math.floor", fmod="math.fmod", frexp="math.frexp", ldexp="math.ldexp",
lerp="math.lerp", log="math.log", log10="math.log10", map="math.map", max="math.max",
min="math.min", modf="math.modf", noise="math.noise", pow="math.pow", rad="math.rad",
random="math.random", round="math.round", sign="math.sign", sin="math.sin", sinh="math.sinh",
sqrt="math.sqrt", tan="math.tan", tanh="math.tanh", huge="math.huge", pi="math.pi",
-- bit32
arshift="bit32.arshift", band="bit32.band", bnot="bit32.bnot",
bor="bit32.bor", btest="bit32.btest", bxor="bit32.bxor",
byteswap="bit32.byteswap", countlz="bit32.countlz", countrz="bit32.countrz",
extract="bit32.extract", replace="bit32.replace", lrotate="bit32.lrotate",
lshift="bit32.lshift", rrotate="bit32.rrotate", rshift="bit32.rshift",
-- constructors
vector="vector.create", vector2="Vector2.new", vector3="Vector3.new",
cframe="CFrame.new", udim="UDim.new", udim2="UDim2.new", color3="Color3.new",
}
local theme = settings().Studio.Theme :: any
local mainText = theme:GetColor(Enum.StudioStyleGuideColor.MainText)
local errorText = theme:GetColor(Enum.StudioStyleGuideColor.ErrorText)
local toolbar = plugin:CreateToolbar("Quick Math Calculator")
local button = toolbar:CreateButton("Calculator", "Quick Math Calculator", "rbxassetid://85861816563977")
button.ClickableWhenViewportHidden = true
local widgetInfo = DockWidgetPluginGuiInfo.new(Enum.InitialDockState.Float, false, false, 120, 40)
local widget = plugin:CreateDockWidgetPluginGui("Quick Math Calculator", widgetInfo)
widget.Title = "Calculator"
local historyFrame = Instance.new("Frame")
historyFrame.Position = UDim2.new(0, 4, 0, 4)
historyFrame.Size = UDim2.new(1, -8, 0, 20)
historyFrame.BackgroundTransparency = 1
historyFrame.Parent = widget
local listLayout = Instance.new("UIListLayout")
listLayout.Padding = UDim.new(0, 4)
listLayout.FillDirection = Enum.FillDirection.Horizontal
listLayout.Parent = historyFrame
local outputBox = Instance.new("TextBox")
outputBox.TextSize = 14
outputBox.TextColor3 = mainText
outputBox.Position = UDim2.new(0, 0, 0, 28)
outputBox.Size = UDim2.new(1, 0, 1, -62)
outputBox.BackgroundTransparency = 1
outputBox.ClearTextOnFocus = false
outputBox.Text = ""
outputBox.Parent = widget
local frame = Instance.new("Frame")
frame.Position = UDim2.new(0, 4, 1, -30)
frame.Size = UDim2.new(1, -8, 0, 26)
frame.BackgroundColor3 = theme:GetColor(Enum.StudioStyleGuideColor.InputFieldBackground)
frame.Parent = widget
local corner = Instance.new("UICorner")
corner.CornerRadius = UDim.new(0, 8)
corner.Parent = frame
local inputBox = Instance.new("TextBox")
inputBox.TextSize = 12
inputBox.TextColor3 = mainText
inputBox.Position = UDim2.new(0, 4, 0, 0)
inputBox.Size = UDim2.new(1, -50, 1, 0)
inputBox.BackgroundTransparency = 1
inputBox.ClearTextOnFocus = false
inputBox.TextXAlignment = Enum.TextXAlignment.Left
inputBox.Text = ""
inputBox.Parent = frame
local import = Instance.new("ImageButton")
import.Image = "rbxasset://textures/ui/MenuBar/arrow_down.png"
import.Position = UDim2.new(1, -42, 1, -21)
import.Size = UDim2.new(0, 16, 0, 16)
import.BackgroundTransparency = 1
import.ScaleType = Enum.ScaleType.Fit
import.Parent = frame
local clear = Instance.new("ImageButton")
clear.Image = "rbxasset://textures/StudioSharedUI/close.png"
clear.Position = UDim2.new(1, -21, 1, -21)
clear.Size = UDim2.new(0, 16, 0, 16)
clear.BackgroundTransparency = 1
clear.ScaleType = Enum.ScaleType.Fit
clear.Parent = frame
local lastCursor = -1
local lastSelection = -1
local historyButtons = {} :: {TextButton}
local function Calculate()
local index = 1
local inject = {}
local tokens = {}
for index, button in historyButtons do
table.insert(inject, "local")
table.insert(inject, string.char(64 + index))
table.insert(inject, "=")
table.insert(inject, button.Text)
end
table.insert(inject, "return")
table.insert(inject, inputBox.Text)
local source = table.concat(inject, " ")
while true do
local startIndex: any, endIndex: any, character: any = source:find("(%S)", index)
if character == nil then break end
local characterType = characterTypes[character]
if characterType == "Alphabet" then
local startIndex: any, endIndex: any, characters: any = source:find("(.[%w_]*)", endIndex)
index = endIndex + 1
table.insert(tokens, characters)
elseif characterType == "Digit" then
local startIndex: any, endIndex: any, characters: any = source:find("(.[%d_.]*)", endIndex)
index = endIndex + 1
table.insert(tokens, characters)
else
index = endIndex + 1
table.insert(tokens, character)
end
end
for index, token in tokens do
if tokens[index - 1] == "." then continue end
local mapped = map[token]
if mapped then tokens[index] = mapped end
end
local func = loadstring(table.concat(tokens, " "))
if func == nil then outputBox.TextColor3 = errorText return end
local success, value = pcall(func)
if success == false then outputBox.TextColor3 = errorText return end
if typeof(value) == "function" then outputBox.TextColor3 = errorText return end
if typeof(value) == "table" then outputBox.TextColor3 = errorText return end
outputBox.TextColor3 = mainText
if typeof(value) == "Vector2" then outputBox.Text = "vector2(" .. tostring(value) .. ")" return end
if typeof(value) == "Vector3" then outputBox.Text = "vector3(" .. tostring(value) .. ")" return end
if typeof(value) == "CFrame" then outputBox.Text = "cframe(" .. tostring(value) .. ")" return end
if typeof(value) == "UDim" then outputBox.Text = "udim(" .. tostring(value) .. ")" return end
if typeof(value) == "UDim2" then outputBox.Text = "udim2(" .. tostring(value) .. ")" return end
if typeof(value) == "Color3" then outputBox.Text = "color3(" .. tostring(value) .. ")" return end
if typeof(value) == "nil" then outputBox.Text = "" return end
outputBox.Text = tostring(value)
end
local function History(value)
local button = Instance.new("TextButton")
button.Text = value
button.Size = UDim2.new(0, 0, 1, 0)
button.AutomaticSize = Enum.AutomaticSize.X
button.TextColor3 = theme:GetColor(Enum.StudioStyleGuideColor.ButtonText)
button.BackgroundColor3 = theme:GetColor(Enum.StudioStyleGuideColor.Button)
button.Parent = historyFrame
button.MouseButton1Down:Connect(function()
local letter = string.char(64 + table.find(historyButtons, button) :: any)
if lastCursor == -1 then
inputBox.Text ..= letter
inputBox:CaptureFocus()
elseif lastSelection == -1 then
inputBox.Text = inputBox.Text:sub(1, lastCursor - 1) .. letter .. inputBox.Text:sub(lastCursor)
inputBox.CursorPosition = lastCursor + 1
else
local min = math.min(lastCursor, lastSelection)
local max = math.max(lastCursor, lastSelection)
inputBox.Text = inputBox.Text:sub(1, min - 1) .. letter .. inputBox.Text:sub(max)
inputBox.CursorPosition = min + 1
end
end)
button.MouseButton2Click:Connect(function()
table.remove(historyButtons, table.find(historyButtons, button))
button:Destroy()
Calculate()
end)
local corner = Instance.new("UICorner")
corner.CornerRadius = UDim.new(0, 4)
corner.Parent = button
local padding = Instance.new("UIPadding")
padding.PaddingLeft = UDim.new(0, 4)
padding.PaddingRight = UDim.new(0, 4)
padding.Parent = button
table.insert(historyButtons, button)
end
button:SetActive(widget.Enabled)
button.Click:Connect(function()
if widget.Enabled then
widget.Enabled = false
else
widget.Enabled = true
task.wait(0.1)
inputBox:CaptureFocus()
end
end)
widget:GetPropertyChangedSignal("Enabled"):Connect(function()
button:SetActive(widget.Enabled)
end)
inputBox:GetPropertyChangedSignal("Text"):Connect(Calculate)
inputBox:GetPropertyChangedSignal("CursorPosition"):Connect(function()
task.wait()
lastCursor = inputBox.CursorPosition
end)
inputBox:GetPropertyChangedSignal("SelectionStart"):Connect(function()
task.wait()
lastSelection = inputBox.SelectionStart
end)
inputBox.FocusLost:Connect(function(enter, input)
if enter == false then return end
History(outputBox.Text)
local restoreCursor = lastCursor
local restoreSelection = lastSelection
task.wait()
inputBox.CursorPosition = restoreCursor
inputBox.SelectionStart = restoreSelection
end)
import.MouseButton1Click:Connect(function()
if outputBox.Text ~= "" then inputBox.Text = outputBox.Text end
end)
clear.MouseButton1Click:Connect(function()
inputBox.Text = ""
end)
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted.
Other Projects
Infinite Terrain
Packet
Suphi’s DataStore Module
Global Framework
Infinite Scripter
Mesh Editor
Quick Math Calculator
Toggle Block Comment
Toggle Decomposition Geometry
Tag Explorer
Suphi’s Linked List Module
Suphi’s Hybrid Linked List Module
Suphi’s RemoteFunction Module
Robux Converter


