Files

gr_parser.src
  • map.to_list = function(shallow = false)
  • list = []
  • for i in self.indexes
  • if typeof(self[i]) == "map" then
  • if shallow == true then
  • list.push([i, self[i]])
  • else
  • list.push([i, self[i].to_list])
  • end if
  • else
  • list.push([i, self[i]])
  • end if
  • end for
  • return list
  • end function
  • list.to_map = function()
  • l = self[0:]
  • map = {}
  • for i in indexes(l)
  • if typeof(l[i][1]) == "list" and l[i][1].len == 2 and typeof(l[i][1][0]) == "string" then
  • map[l[i][0]] = l[i][1].to_map
  • else
  • map[l[i][0]] = l[i][1]
  • end if
  • end for
  • return map
  • end function
  • list.each = function(func)
  • result = self[0:] //list copy.
  • for i in indexes(self)
  • func(result[i])
  • end for
  • end function
  • map.each = function(func)
  • list = self.to_list(true)
  • result = list[0:] //list copy.
  • for i in indexes(list)
  • func(result[i][0], result[i][1])
  • end for
  • end function
  • list.map = function(func)
  • result = self[0:] //list copy.
  • for i in indexes(self)
  • result[i] = func(result[i])
  • end for
  • return result
  • end function
  • list.reject = function(func)
  • result = self[0:] //list copy.
  • i = 0
  • while i < result.len
  • if func(result[i]) == true then
  • result.remove(i)
  • continue
  • end if
  • i = i + 1
  • end while
  • return result
  • end function
  • list.select = function(func)
  • f = function(o)
  • return not func(o)
  • end function
  • return self.reject(@f)
  • end function
  • // do not rename funcc to to func it will infinite loop
  • list.lsort = function(funcc)
  • f = function(i)
  • return {"sort_key": funcc(i), "obj": i}
  • end function
  • result = self.map(@f)
  • result = result.sort("sort_key")
  • f = function(i)
  • return i["obj"]
  • end function
  • return result.map(@f)
  • end function
  • list.flat = function()
  • result = []
  • for i in self
  • if typeof(i) == "list" then
  • result = result + i.flat
  • else
  • result.push(i)
  • end if
  • end for
  • return result
  • end function
  • list.uniq = function()
  • result = []
  • for i in self
  • if result.indexOf(i) == null then result.push(i)
  • end for
  • return result
  • end function
  • list.has_any = function(value)
  • for i in self
  • if i == value then return true
  • end for
  • return false
  • end function
  • list.min = function()
  • min = self[0]
  • for item in self
  • if item < min then
  • min = item
  • end if
  • end for
  • return min
  • end function
  • list.max = function()
  • max = self[0]
  • for item in self
  • if item > max then
  • max = item
  • end if
  • end for
  • return max
  • end function
  • SafeMap = {}
  • SafeMap.methods = ["hasIndex", "indexOf", "indexes", "len", "pop", "push", "remove", "shuffle", "sum", "values"]
  • SafeMap.escaped = []
  • for i in SafeMap.methods.indexes
  • SafeMap.escaped.push(char(2000 + i))
  • end for
  • SafeMap.escape = function(index)
  • if self.methods.indexOf(index) != null then
  • index = self.escaped[self.methods.indexOf(index)]
  • end if
  • return index
  • end function
  • SafeMap.unescape = function(index)
  • if self.escaped.indexOf(index) != null then
  • index = self.methods[self.escaped.indexOf(index)]
  • end if
  • return index
  • end function
  • SafeMap.set = function(dict, index, value)
  • index = self.escape(index)
  • dict[index] = value
  • return dict
  • end function
  • SafeMap.get = function(dict, index)
  • index = self.escape(index)
  • return dict[index]
  • end function
  • SafeMap.hasIndex = function(dict, index)
  • index = self.escape(index)
  • return dict.hasIndex(index)
  • end function
  • SafeMap.indexOf = function(dict, value)
  • index = dict.indexOf(value)
  • index = self.unescape(index)
  • return index
  • end function
  • SafeMap.indexes = function(dict)
  • indexes = dict.indexes
  • for i in indexes.indexes
  • indexes[i] = self.unescape(indexes[i])
  • end for
  • return indexes
  • end function
  • SafeMap.len = function(dict)
  • return dict.len
  • end function
  • SafeMap.pop = function(dict)
  • return dict.pop
  • end function
  • SafeMap.push = function(dict, index)
  • index = self.escape(index)
  • return dict.push(index)
  • end function
  • SafeMap.remove = function(dict, index)
  • index = self.escape(index)
  • return dict.remove(index)
  • end function
  • SafeMap.shuffle = function(dict)
  • return dict.shuffle
  • end function
  • SafeMap.sum = function(dict)
  • return dict.sum
  • end function
  • SafeMap.values = function(dict)
  • return dict.values
  • end function
  • // require lst
  • // require SafeMap
  • Lzw = {}
  • Lzw.generate_dict = function(length)
  • result = {}
  • for i in range(length - 1).sort
  • result[char(i)] = char(i)
  • end for
  • return result
  • end function
  • Lzw.compress = function(uncompressed)
  • dict_size = 256
  • dictionary = self.generate_dict(dict_size)
  • w = ""
  • result = []
  • for c in uncompressed.values
  • wc = w + c
  • //if dictionary.hasIndex(wc) then
  • if SafeMap.hasIndex(dictionary, wc) then
  • w = wc
  • else
  • //result.push(dictionary[w])
  • result.push(SafeMap.get(dictionary, w))
  • //dictionary[wc] = dict_size
  • SafeMap.set(dictionary, wc, dict_size)
  • dict_size = dict_size + 1
  • w = c
  • end if
  • end for
  • //if w != "" then result.push(dictionary[w])
  • if w != "" then result.push(SafeMap.get(dictionary, w))
  • return result
  • end function
  • Lzw.decompress = function(compressed)
  • dict_size = 256
  • dictionary = self.generate_dict(dict_size)
  • w = compressed[0]
  • result = compressed[0]
  • compressed = compressed[1:]
  • for k in compressed
  • //if dictionary.hasIndex(k) then
  • if SafeMap.hasIndex(dictionary, k) then
  • //entry = dictionary[k]
  • entry = SafeMap.get(dictionary, k)
  • else if k == dict_size then
  • entry = w + w[0]
  • else
  • exit("Bad compressed k: " + k)
  • end if
  • result = result + entry
  • //dictionary[dict_size] = w + entry[0]
  • SafeMap.set(dictionary, dict_size, w + entry[0])
  • dict_size = dict_size + 1
  • w = entry
  • end for
  • return result
  • end function
  • // require lst
  • Encoder = {}
  • Encoder.CELL_LEN = 14
  • char_set = []
  • char_set.push(range(48, 57)) // numbers
  • char_set.push(range(65, 90)) // capital_letters
  • char_set.push(range(97, 122)) // letters
  • char_set.push(range(128, 193)) // extended
  • char_set = char_set.flat // <- 7 bit char set
  • Encoder.CHAR_SET = char_set
  • // UTILS ------------------------------------------------------
  • Encoder.Utils = {}
  • Encoder.Utils.to_bin = function(n)
  • if n == 0 then return "0"
  • if n == 1 then return "1"
  • return self.to_bin(floor(n / 2)) + str(n % 2)
  • end function
  • Encoder.Utils.to_int = function(n)
  • n = n.values
  • n.reverse
  • r = 0
  • for i in n.indexes
  • if n[i] == "1" then
  • r = r + 2 ^ i
  • end if
  • end for
  • return r
  • end function
  • Encoder.Utils.divide = function(s, n)
  • if s.len == 0 then
  • return []
  • end if
  • if s.len < n then
  • //prepend = "0" * (n - s.len)
  • //s = prepend + s
  • return [s]
  • end if
  • return self.divide(s[n:], n).insert(0, s[0:n])
  • end function
  • // -------------------------------------------------------------
  • Encoder.encode = function(lzw)
  • l = lzw[0:]
  • CELL_SIZE = 0
  • for i in l.indexes
  • if l[i] isa string then l[i] = l[i].code
  • l[i] = self.Utils.to_bin(l[i])
  • if l[i].len > CELL_SIZE then CELL_SIZE = l[i].len
  • end for
  • for i in l.indexes
  • l[i] = "0" * (CELL_SIZE - l[i].len) + l[i]
  • end for
  • l = l.join("")
  • FAT_ADDED = l.len % 7
  • if FAT_ADDED > 0 then FAT_ADDED = 7 - FAT_ADDED
  • l = l + "0" * FAT_ADDED
  • l = self.Utils.divide(l, 7)
  • fat_bin = self.Utils.to_bin(FAT_ADDED)
  • l.insert(0, "0" * (7 - fat_bin.len) + fat_bin)
  • cell_bin = self.Utils.to_bin(CELL_SIZE)
  • l.insert(0, "0" * (7 - cell_bin.len) + cell_bin)
  • l = self.Utils.divide(l.join(""), 7)
  • //print l
  • for i in l.indexes
  • l[i] = char(self.CHAR_SET[self.Utils.to_int(l[i])])
  • end for
  • return l.join("")
  • end function
  • Encoder.decode = function(string)
  • l = string.values
  • for i in l.indexes
  • l[i] = self.Utils.to_bin(self.CHAR_SET.indexOf(l[i].code))
  • l[i] = "0" * (7 - l[i].len) + l[i]
  • end for
  • //l[-1] = l[-1][2:]
  • l = l.join("")
  • CELL_SIZE = self.Utils.to_int(l[0:7])
  • FAT_ADDED = self.Utils.to_int(l[7: 14])
  • l = self.Utils.divide(l[14:], 7)
  • //print l
  • if FAT_ADDED > 0 then l[-1] = l[-1][0:FAT_ADDED * -1]
  • //print l
  • l = self.Utils.divide(l.join(""), CELL_SIZE)
  • for i in l.indexes
  • l[i] = self.Utils.to_int(l[i])
  • if l[i] < 256 then l[i] = char(l[i])
  • end for
  • return l
  • end function
  • //This implementation deviates from RFC 7159 - The JavaScript Object Notation (JSON) Data Interchange Format <https://tools.ietf.org/html/rfc7159> in the following ways:
  • //Section 6 (Numbers):
  • // Leading zeros are allowed
  • // Infinity, -Infinity, NaN are considered valid numbers
  • //Section 7 (Strings):
  • // Escaping characters is not implemented
  • // Literal double quote is represented as "" in a string
  • //usage:
  • //json = new JSON
  • //string = json.to_string(object)
  • //object = json.to_object(string)
  • JSON = {}
  • JSON.JSON_QUOTE = """"
  • JSON.JSON_WHITESPACE = [char(9), char(10), char(13), char(32)] //[TAB, LF, CR, Space]
  • JSON.JSON_SYNTAX = [",",":","[","]","{","}"]
  • JSON.NUMBER_SYNTAX = ["-","+","E","e","."]
  • JSON.NULL = null
  • JSON.sLexString=function(string)
  • if string[0] == self.JSON_QUOTE then
  • string = string[1:]
  • else
  • return [self.NULL, string]
  • end if
  • json_string = ""
  • strlen = string.len
  • if strlen > 0 then
  • i = 0
  • while i < strlen
  • if string[i] == "\" and string[i+1] == self.JSON_QUOTE then
  • i = i + 2
  • json_string = json_string + self.JSON_QUOTE
  • continue
  • end if
  • if string[i] == self.JSON_QUOTE then
  • i = i + 1
  • return [json_string, string[i:]]
  • end if
  • json_string = json_string + string[i]
  • i = i + 1
  • end while
  • end if
  • exit("<color=#ff0000>JSON string lexer error: Expected end-of-string quote")
  • end function
  • JSON.sLexNumber=function(string)
  • strlen = string.len
  • if strlen > 8 and string[:9] == "-Infinity" then
  • return ["-Infinity".val, string[9:]]
  • else if strlen > 7 and string[:8] == "Infinity" then
  • return ["Infinity".val, string[8:]]
  • else if strlen > 2 and string[:3] == "NaN" then
  • return ["NaN".val, string[3:]]
  • end if
  • json_number = ""
  • for c in string
  • if (c.code > 47 and c.code < 58) or self.NUMBER_SYNTAX.indexOf(c) != null then
  • json_number = json_number + c
  • else
  • break
  • end if
  • end for
  • number = json_number.val
  • if number == 0 and json_number != "0" then return [self.NULL, string]
  • return [number, string[json_number.len:]]
  • end function
  • JSON.sLexBool=function(string)
  • strlen=string.len
  • if strlen > 3 and string[:4] == "true" then return [true, string[4:]]
  • if strlen > 4 and string[:5] == "false" then return [false, string[5:]]
  • return [self.NULL, string]
  • end function
  • JSON.sLexNull=function(string)
  • if string.len > 3 and string[:4] == "null" then return [true, string[4:]]
  • return [false, string]
  • end function
  • JSON.sLexWhitespace=function(string)
  • if self.JSON_WHITESPACE.indexOf(string[0]) != null then
  • return [string[0], string[1:]]
  • end if
  • return [self.NULL, string]
  • end function
  • JSON.sLexSyntax=function(string)
  • if self.JSON_SYNTAX.indexOf(string[0]) != null then
  • return [string[0], string[1:]]
  • end if
  • return [self.NULL, string]
  • end function
  • JSON.sLex=function(string)
  • tokens = []
  • while string
  • res = self.sLexString(string)
  • if res[0] != null then
  • tokens.push({"token":"string","value":res[0]})
  • string=res[1]
  • continue
  • end if
  • res = self.sLexNumber(string)
  • if res[0] != null then
  • tokens.push({"token":"number","value":res[0]})
  • string=res[1]
  • continue
  • end if
  • res = self.sLexBool(string)
  • if res[0] != null then
  • tokens.push({"token":"bool","value":res[0]})
  • string=res[1]
  • continue
  • end if
  • res = self.sLexNull(string)
  • if res[0] == true then
  • tokens.push({"token":"null","value":self.NULL})
  • string=res[1]
  • continue
  • end if
  • res = self.sLexSyntax(string)
  • if res[0] != null then
  • tokens.push({"token":"syntax","value":res[0]})
  • string=res[1]
  • continue
  • end if
  • res = self.sLexWhitespace(string)
  • if res[0] != null then
  • string=res[1]
  • continue
  • end if
  • exit("<color=#ff0000>JSON lexer error: Unexpected character: "+string[0])
  • end while
  • return tokens
  • end function
  • JSON.sParseList=function(tokens)
  • if tokens[0] == {"token":"syntax","value":"]"} then return [[], tokens[1:]]
  • json_list = []
  • while tokens
  • res = self.sParse(tokens)
  • json_list.push(res[0])
  • tokens = res[1]
  • if tokens[0] == {"token":"syntax","value":"]"} then
  • return [json_list, tokens[1:]]
  • else if tokens[0] != {"token":"syntax","value":","} then
  • exit("<color=#ff0000>JSON parser error: Expected comma after object in list")
  • end if
  • tokens = tokens[1:]
  • end while
  • exit("<color=#ff0000>JSON list parser error: Expected end-of-list bracket")
  • end function
  • JSON.sParseMap=function(tokens)
  • if tokens[0] == {"token":"syntax","value":"}"} then return [{}, tokens[1:]]
  • json_map = {}
  • while tokens
  • if tokens[0].token == "string" or tokens[0].token == "number" then
  • json_key = tokens[0].value
  • tokens = tokens[1:]
  • else
  • exit("<color=#ff0000>JSON map parser error: Expected string or number key, got: "+tokens[0])
  • end if
  • if tokens[0] != {"token":"syntax","value":":"} then
  • exit("<color=#ff0000>JSON map parser error: Expected "":"" after key in map, got: "+tokens[0])
  • end if
  • res = self.sParse(tokens[1:])
  • json_map[json_key]=res[0]
  • tokens=res[1]
  • if tokens[0] == {"token":"syntax","value":"}"} then
  • return [json_map, tokens[1:]]
  • else if tokens[0] != {"token":"syntax","value":","} then
  • exit("<color=#ff0000>JSON map parser error: Expected "","" after pair in map, got: "+tokens[0])
  • end if
  • tokens = tokens[1:]
  • end while
  • exit("<color=#ff0000>JSON map parser error: Expected end-of-map brace")
  • end function
  • JSON.sParse=function(tokens)
  • if tokens then
  • if tokens[0] == {"token":"syntax","value":"["} then
  • return self.sParseList(tokens[1:])
  • else if tokens[0] == {"token":"syntax","value":"{"} then
  • return self.sParseMap(tokens[1:])
  • end if
  • return [tokens[0].value, tokens[1:]]
  • end if
  • return null
  • end function
  • JSON.oParseList=function(list)
  • list_string = "["
  • listlen = list.len
  • if listlen then
  • if listlen > 1 then
  • for i in range(0,listlen-2)
  • list_string = list_string + self.to_string(list[i]) + ","
  • end for
  • end if
  • list_string = list_string + self.to_string(list[-1])
  • end if
  • return list_string + "]"
  • end function
  • JSON.oParseMap=function(map)
  • map_string = "{"
  • mapkeys = map.indexes
  • maplen = mapkeys.len
  • if maplen then
  • if maplen > 1 then
  • for i in range(0,maplen-2)
  • if typeof(mapkeys[i]) == "string" then
  • map_string = map_string + """" + mapkeys[i] + """" + ":" + self.to_string(map[mapkeys[i]]) + ","
  • else
  • map_string = map_string + mapkeys[i] + ":" + self.to_string(map[mapkeys[i]]) + ","
  • end if
  • end for
  • end if
  • if typeof(mapkeys[-1]) == "string" then
  • map_string = map_string + """" + mapkeys[-1] + """" + ":" + self.to_string(map[mapkeys[-1]])
  • else
  • map_string = map_string + mapkeys[-1] + ":" + self.to_string(map[mapkeys[-1]])
  • end if
  • end if
  • return map_string + "}"
  • end function
  • JSON.to_object=function(string)
  • return self.sParse(self.sLex(string))[0]
  • end function
  • JSON.to_string=function(object)
  • if typeof(object) == "string" then
  • return """" + object.replace("""", "\""") + """"
  • else if typeof(object) == "number" then
  • return str(object)
  • else if object == null then
  • return null
  • else if typeof(object) == "list" then
  • return self.oParseList(object)
  • else
  • return self.oParseMap(object)
  • end if
  • end function
  • // --------------------------------------
  • get_folder_table = function(folder, table=null, parent="")
  • if table == null then table = {}
  • index = table.len
  • obj = {"parent": parent, "type": "folder", "name": folder.name}
  • table[str(index)] = obj
  • parent = str(index)
  • index = index + 1
  • scripts = folder.get_files
  • folders = folder.get_folders
  • for script in scripts
  • print "compressing " + script.name
  • compressed_content = Encoder.encode(Lzw.compress(script.get_content))
  • obj = {"parent": parent, "type": "script", "name": script.name, "content": compressed_content}
  • table[str(index)] = obj
  • index = index + 1
  • end for
  • for folder in folders
  • get_folder_table(folder, table, parent)
  • end for
  • return table
  • end function
  • computer = get_shell.host_computer
  • root_path = current_path
  • root_folder = computer.File(root_path)
  • import_folder = function()
  • json = new JSON
  • root_folder_name = user_input("(optional, you can press enter to skip and use the root folder name provided in the import string)\nroot folder name: \n")
  • export_string = user_input("export string: \n").replace(char(10), "")
  • print char(10) * 50
  • table = json.to_object(export_string)
  • file_table = {}
  • for value in table.values
  • key = table.indexOf(value)
  • file_name = value["name"].replace(" ", "_")
  • if value["parent"] == "" then
  • parent_folder = root_folder
  • if root_folder_name != "" then file_name = root_folder_name
  • file_path = parent_folder.path + "/" + file_name
  • if computer.File(file_path) then computer.File(file_path).delete //clear
  • else
  • parent_folder = file_table[value["parent"]]["file"]
  • file_path = parent_folder.path + "/" + file_name
  • end if
  • if value["type"] == "folder" then
  • f_out = computer.create_folder(parent_folder.path, file_name)
  • if f_out != 1 then
  • print(file_path)
  • exit(f_out)
  • end if
  • file = computer.File(file_path)
  • else if value["type"] == "script" then
  • f_out = computer.touch(parent_folder.path, file_name)
  • if f_out != 1 then
  • print(file_path)
  • exit(f_out)
  • end if
  • file = computer.File(file_path)
  • print "decompressing " + value["name"]
  • decompressed_content = Lzw.decompress(Encoder.decode(value["content"]))
  • file.set_content(decompressed_content)
  • end if
  • file_table[key] = {"parent": value["parent"], "file": file}
  • print(file_path + " " + value["type"] +" created")
  • end for
  • end function
  • export_folder = function()
  • full_path = user_input("full path of the folder:\n")
  • folder = computer.File(full_path)
  • if not folder then exit("ERROR: path is invalid")
  • export_obj = get_folder_table(folder)
  • print("\n\nthis is your export string:\n\n")
  • json = new JSON
  • export_string = json.to_string(export_obj)
  • print char(10)
  • print(export_string)
  • print char(10) * 2
  • end function
  • print("<b>grey repo parser (www.greyrepo.xyz/posts/folder-parser)</b>\nactions:\n[1] import project\n[2] export a local folder")
  • input = user_input("select action:\n")
  • if input == "1" then import_folder()
  • if input == "2" then export_folder()