Advertisement
AlewAlow

sussy gyat dog balls

Sep 29th, 2023 (edited)
174
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 7.90 KB | None | 0 0
  1. local STRING_BORDERS = {"'", '"', "*", "+", "$", "#", "@", "!", "^", "_"}
  2. local STRING_BORDERS_MAP = {}
  3. local SHOULD_BE_REPLACED_KEY = {}
  4.  
  5. for _, v in STRING_BORDERS do
  6.     STRING_BORDERS_MAP[v] = true
  7. end
  8.  
  9. local Parser = {}
  10. Parser.__index = Parser
  11.  
  12. function Parser.new(text, index)
  13.     local self = setmetatable({}, Parser)
  14.     self.Text = text
  15.     self.Index = index or 1
  16.     return self
  17. end
  18.  
  19. function Parser:GetNextCharacter()
  20.     local letter = self.Text:sub(self.Index, self.Index)
  21.     self.Index += #letter
  22.     return letter
  23. end
  24.  
  25. function Parser:GetNextNumber()
  26.     local hasFoundDot = false
  27.    
  28.     local copy = self:Copy()
  29.     local text = self:GetNextSolidCharacter()
  30.    
  31.     while self:IsActive() do
  32.         local copy = self:Copy()
  33.         local digit = copy:GetNextCharacter()
  34.         if digit == "." then
  35.             if hasFoundDot then
  36.                 break
  37.             end
  38.  
  39.             hasFoundDot = true
  40.         elseif not tonumber(digit) then
  41.             break
  42.         end
  43.        
  44.         self:Apply(copy)
  45.         text = text..digit
  46.     end
  47.    
  48.     local number = tonumber(text)
  49.     if not number then
  50.         return nil
  51.     end
  52.    
  53.     return number
  54. end
  55.  
  56. function Parser:GetNextSolidCharacter()
  57.     local nextChar repeat
  58.         nextChar = self:GetNextCharacter()
  59.     until nextChar ~= " " and nextChar ~= "\n" and nextChar ~= "\t"
  60.  
  61.     return nextChar
  62. end
  63.  
  64. function Parser:GetTextLeftUntilE(stops)
  65.     local map = {}
  66.     for _, v in stops do
  67.         map[v] = true
  68.     end
  69.    
  70.     local text = ""
  71.     while self:IsActive() do
  72.         local char = self:GetNextCharacter()
  73.         if map[char] then
  74.             break
  75.         end
  76.  
  77.         text ..= char
  78.     end
  79.  
  80.     return text
  81. end
  82.  
  83. function Parser:GetTextLeftUntil(stop)
  84.     return self:GetTextLeftUntilE({stop})
  85. end
  86.  
  87. function Parser:GetTextLeft()
  88.     return self:GetTextLeftUntil()
  89. end
  90.  
  91. function Parser:GetNextWord()
  92.     local word = ""
  93.     while self:IsActive() and word == "" do
  94.         word = self:GetTextLeftUntilE({"\t", "\n", " "})
  95.     end
  96.    
  97.     return word
  98. end
  99.  
  100. function Parser:GetWordsLeft()
  101.     local words = {}
  102.     while not self:HasFinished() do
  103.         local word = self:GetNextWord()
  104.         if word == "" then
  105.             break
  106.         end
  107.  
  108.         table.insert(words, word)
  109.     end
  110.  
  111.     return words
  112. end
  113.  
  114. function Parser:HasFinished()
  115.     return self.Index > #self.Text
  116. end
  117.  
  118. function Parser:IsActive()
  119.     return not self:HasFinished()
  120. end
  121.  
  122. function Parser:Copy()
  123.     return Parser.new(self.Text, self.Index)
  124. end
  125.  
  126. function Parser:Apply(parser)
  127.     self.Text = parser.Text
  128.     self.Index = parser.Index
  129. end
  130.  
  131. local function convertTableToString(main)
  132.     local result = ""
  133.     local nameMap = {}
  134.     local tables = {}
  135.     local nextName = 1
  136.  
  137.     local function addToNameMap(tbl)
  138.         if nameMap[tbl] then
  139.             return
  140.         end
  141.        
  142.         table.insert(tables, tbl)
  143.         nameMap[tbl] = nextName
  144.         nextName += 1
  145.  
  146.         local metatable = getmetatable(tbl)
  147.         if metatable then
  148.             addToNameMap(metatable)
  149.         end
  150.  
  151.         for k, v in tbl do
  152.             if type(k) == "table" then
  153.                 addToNameMap(k)
  154.             end
  155.  
  156.             if type(v) == "table" then
  157.                 addToNameMap(v)
  158.             end
  159.         end
  160.     end
  161.  
  162.     local function convertItem(item)
  163.         local itemType = type(item)
  164.         if itemType == "string" then
  165.             local border
  166.             for _, possibleBorder in STRING_BORDERS do
  167.                 if not item:find(possibleBorder) then
  168.                     border = possibleBorder
  169.                     break
  170.                 end
  171.             end
  172.  
  173.             if not border then
  174.                 error("The string you've entered has all the possible borders")
  175.             end
  176.  
  177.             return border..item..border
  178.         end
  179.  
  180.         return
  181.             if itemType == "number" then tostring(item)
  182.             elseif itemType == "boolean" then (item and "true" or "false")
  183.             elseif itemType == "table" then `i {nameMap[item]}`
  184.             else error("invalid item type "..itemType)
  185.     end
  186.  
  187.     addToNameMap(main)
  188.  
  189.     for name, tbl in tables do
  190.         local stringTbl = ""
  191.  
  192.         for k, v in tbl do
  193.             local stringKey = convertItem(k)
  194.             local stringValue = convertItem(v)
  195.  
  196.             stringTbl ..= `\t[{stringKey}] {stringValue};\n`
  197.         end
  198.  
  199.         stringTbl = string.format("{\n%s}", stringTbl)
  200.        
  201.         local metatable = getmetatable(tbl)
  202.         if metatable then
  203.             stringTbl = `{stringTbl} m {convertItem(metatable)}`
  204.         end
  205.        
  206.         stringTbl ..= "\n"
  207.         result ..= stringTbl
  208.     end
  209.  
  210.     return result
  211. end
  212.  
  213. local function getNextItem(parser)
  214.     local oldParser = parser:Copy()
  215.     local nextChar = parser:GetNextSolidCharacter()
  216.  
  217.     if STRING_BORDERS_MAP[nextChar] then
  218.         return parser:GetTextLeftUntil(nextChar)
  219.     end
  220.  
  221.     if nextChar == "i" then
  222.         local name = parser:GetNextNumber()
  223.         if not name or math.floor(name) ~= name then
  224.             error("the table name given is not an integer")
  225.         end
  226.  
  227.         return {
  228.             [SHOULD_BE_REPLACED_KEY] = true,
  229.             Name = name,
  230.         }
  231.     end
  232.  
  233.     if nextChar == "{" then
  234.         local tbl = {}
  235.  
  236.         while parser:IsActive() do
  237.             local copy = parser:Copy()
  238.             if copy:GetNextSolidCharacter() ~= "[" then
  239.                 break
  240.             end
  241.  
  242.             parser:Apply(copy)
  243.  
  244.             local key = getNextItem(parser)
  245.             if parser:GetNextSolidCharacter() ~= "]" then
  246.                 error("given unexpected content to a key")
  247.             end
  248.  
  249.             local value = getNextItem(parser)
  250.             if parser:GetNextSolidCharacter() ~= ";" then
  251.                 print("VALUE", value)
  252.                 error("given unexpected content to a value")
  253.             end
  254.  
  255.             tbl[key] = value
  256.         end
  257.  
  258.         if parser:HasFinished() then
  259.             error("table never ended")
  260.         end
  261.        
  262.         local nextCharacter = parser:GetNextSolidCharacter()
  263.         if nextCharacter ~= "}" then
  264.             error("given unexcepted content to a table")
  265.         end
  266.        
  267.         local copy = parser:Copy()
  268.         local word = copy:GetNextWord()
  269.         if word == "m" then
  270.             local metatable = getNextItem(copy)
  271.             if type(metatable) ~= "table" then
  272.                 error("invalid metatable type")
  273.             end
  274.  
  275.             setmetatable(tbl, metatable)
  276.             parser:Apply(copy)
  277.         end
  278.        
  279.         return tbl
  280.     end
  281.  
  282.     parser:Apply(oldParser)
  283.  
  284.     local number = parser:GetNextNumber()
  285.     if number then
  286.         return number
  287.     end
  288.  
  289.     parser:Apply(oldParser)
  290.    
  291.     local word = parser:GetNextSolidCharacter()..parser:GetTextLeftUntil("e").."e"
  292.     if word == "true" then
  293.         return true
  294.     end
  295.  
  296.     if word == "false" then
  297.         return false
  298.     end
  299.    
  300.     error("invalid input given")
  301. end
  302.  
  303. local function convertStringToTable(str)
  304.     local parser = Parser.new(str)
  305.     local items = {}
  306.    
  307.     while true do
  308.         local copy = parser:Copy()
  309.         if copy:GetNextSolidCharacter() == "" then
  310.             break
  311.         end
  312.        
  313.         local item = getNextItem(parser)
  314.         table.insert(items, item)
  315.     end
  316.    
  317.     local function validateItemName(name)
  318.         local item = items[name]
  319.         if item == nil then
  320.             error("invalid item name given")
  321.         end
  322.        
  323.         return item
  324.     end
  325.    
  326.     local loopedThrough = {}
  327.    
  328.     local function forEachTable(tbl)
  329.         if loopedThrough[tbl] then
  330.             return
  331.         end
  332.        
  333.         loopedThrough[tbl] = true
  334.        
  335.         for k, v in tbl do
  336.             if type(k) == "table" and k[SHOULD_BE_REPLACED_KEY] then
  337.                 tbl[validateItemName(k.Name)] = v
  338.                 tbl[k] = nil
  339.             end
  340.         end
  341.  
  342.         for k, v in tbl do
  343.             if type(v) == "table" and v[SHOULD_BE_REPLACED_KEY] then
  344.                 tbl[k] = validateItemName(v.Name)
  345.             end
  346.         end
  347.  
  348.         local metatable = getmetatable(tbl)
  349.         if metatable and metatable[SHOULD_BE_REPLACED_KEY] then
  350.             local newMetatable = validateItemName(metatable.Name)
  351.             if type(newMetatable) ~= "table" then
  352.                 error("invalid metatable type")
  353.             end
  354.  
  355.             setmetatable(tbl, newMetatable)
  356.         end
  357.        
  358.         for k, v in tbl do
  359.             if type(k) == "table" then
  360.                 forEachTable(k)
  361.             end
  362.            
  363.             if type(v) == "table" then
  364.                 forEachTable(v)
  365.             end
  366.         end
  367.        
  368.         local metatable = getmetatable(tbl)
  369.         if metatable then
  370.             forEachTable(metatable)
  371.         end
  372.     end
  373.    
  374.     for name, item in items do
  375.         if type(item) == "table" then
  376.             forEachTable(item)
  377.         end
  378.     end
  379.    
  380.     return items[1]
  381. end
  382.  
  383. local input = {
  384.     yes = true,
  385.     no = false,
  386.  
  387.     nested = {
  388.         yes = 1,
  389.         no = 0,
  390.     },
  391.  
  392.     metatable = setmetatable({}, {
  393.         yes = 424,
  394.     })
  395. }
  396.  
  397. input.cyclic = input
  398.  
  399.  
  400. local str = convertTableToString(input)
  401.  
  402. print(str)
  403.  
  404. local tbl = convertStringToTable(str)
  405.  
  406. print(tbl)
  407. print(getmetatable(tbl.metatable))
  408. print(convertTableToString(tbl))
  409.  
  410.  
  411. -- "m" sets the metatable
  412. print(convertStringToTable([[
  413. {
  414.     ["gyat lil bro"] -5.30;
  415.     [531] true;
  416.     [53] "yuh";
  417.     [i 1] i 1;
  418.     [i 2] i 3;
  419.     [i 3] {} m {};
  420. }
  421. true
  422. false
  423. ]]))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement