Advertisement
Guest User

Ded by 22

a guest
Mar 27th, 2017
49
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 7.25 KB | None | 0 0
  1. function AssembleASM(input,output)
  2.     if(not fs.exists(input))then error("File doesnt exist: " .. input) end
  3.     if(fs.exists(output))then error("File exists: " .. output) end
  4.     local labels = {}
  5.     local vars = {}
  6.     local keyword_var = "define"
  7.     local keyword_label = ":"
  8.     local online = 1
  9.     local codeline = 0
  10.     local programstart = 600
  11.     print("Reading file...")
  12.     -- Safer to read file first, then compile as the fs hook is closed, and they is no risk of data loss.
  13.     local source = fs.open(input,"r")
  14.     local code = {}
  15.     local line = source.readLine()
  16.     while line do
  17.       code[#code+1] = line
  18.       line = source.readLine()
  19.     end
  20.     source.close()
  21.     -- Compile Variables and labels, check for syntax errors
  22.     print("Initializing...")
  23.     for i = 1, #code do
  24.         -- Handle variables
  25.         if(#code[i]:gsub("%s+","") ~= 0)then
  26.             codeline = codeline + 1
  27.         end
  28.         if(code[i]:find(keyword_var))then
  29.              local val = str_shearWord(code[i],keyword_var)
  30.              local nargs = {}
  31.              -- Take spaces out of string, then split it into 2 variables
  32.              val = val:gsub("%s+", "")
  33.              -- Split string by $
  34.              for word in string.gmatch(val, '([^$]+)') do
  35.                 table.insert(nargs, word)
  36.              end
  37.                 if(#nargs > 2)then error("Syntax error line " .. online .. ": " .. code[i]) end
  38.                 -- Convert ASCII to hex
  39.                 if(tonumber(nargs[2]) == nil)then
  40.                     nargs[2] = string.byte(nargs[2])
  41.                 end
  42.                -- if(_G.ASM._HEXENCODE[string.upper(nargs[1])])then error("Syntax error line " .. online .. ": " .. code[i]) end
  43.              vars[nargs[1]] = nargs[2]
  44.             -- print(nargs[1] .. ": " .. vars[nargs[1]])
  45.         end
  46.         -- Handle labels
  47.         if(code[i]:find(keyword_label))then
  48.             local val = code[i]:gsub("%s+","")
  49.             local nargs = {}
  50.              for word in string.gmatch(val, '([^:]+)') do
  51.                 table.insert(nargs, word)
  52.              end
  53.              if(#nargs > 1 or nargs == nil)then
  54.                  error("Syntax error line " .. online .. ": " .. code[i])
  55.              end
  56.              labels[nargs[1]] = codeline
  57.              print(nargs[1] .. ": " .. labels[nargs[1]])
  58.             -- print(nargs[1] .. ": " .. labels[nargs[1]])
  59.         end
  60.         online = online + 1
  61.     end
  62.  
  63.     -- Get Bytes Per line
  64.     codeline = 0
  65.     online = 1
  66.     linebytes = {}
  67.     local code_backup = code -- LUA bug where this variable acts like a pointer and still writes to code, screw lua.
  68.     print("Getting Bytes...")
  69.     for i = 1, #code_backup do
  70.         if(#code_backup[i]:gsub("%s+","") ~= 0 and not code_backup[i]:find(keyword_label) and not code_backup[i]:find(keyword_var))then
  71.             local op  = string.upper(code_backup[i]:gsub("%s+",""):sub(1,3))
  72.             local vtype = code_backup[i]:gsub("%s+",""):sub(4,4)
  73.             local val = code_backup[i]:gsub("%s+",""):sub(4,#code_backup[i])
  74.             if(val:sub(1,1) == "#")then val = val:sub(2,#val) end
  75.             if(not _G.ASM._HEXENCODE[op])then error("Syntax error line " .. online .. ": " .. code_backup[i]) end
  76.             if(vars[val] ~= nil)then
  77.                 if(_G.ASM._HEXENCODE[op]['REL'] ~= nil)then
  78.                     error("Syntax error line " .. online .. ": " .. code_backup[i])
  79.                 end
  80.                 if(vtype == "#")then
  81.                     code_backup[i] = op .. " #$" .. vars[val]
  82.                 else
  83.                     if(not tonumber(vars[val]))then error("Syntax error line " .. online .. ": " .. code_backup[i]) end
  84.                     code_backup[i] = op .. " $" .. vars[val]
  85.                 end
  86.             elseif(labels[val] ~= nil)then
  87.                 if(_G.ASM._HEXENCODE[op]['REL'] ~= nil)then
  88.                     code_backup[i] = op .. " *+" .. "00"
  89.                 else
  90.                     local newBase = toHex(tonumber(programstart,16) + labels[val]-1)
  91.                     if(#newBase < 4)then newBase = string.rep("0",4-#newBase) .. newBase end
  92.                     code_backup[i] = op .. " $" .. newBase
  93.                 end
  94.             end
  95.             codeline = codeline + 1
  96.             local op, otype, num = procInstructionType(code_backup[i],false,false)
  97.             if(lineB == "op")then error("Syntax error line " .. online .. ": " .. code_backup[i]) end
  98.             local lineB = getInstuctionBytes(op,otype)
  99.             if(lineB == "err")then error("Syntax error line " .. online .. ": " .. code_backup[i]) end
  100.             linebytes[#linebytes+1] = lineB
  101.         end
  102.         online = online + 1
  103.     end
  104.     -- Compile Code substitute variables and labels, check syntax
  105.     -- Branch labels and jump labels, are controlled based on additions to the base program start
  106.     codeline = 0
  107.     online = 1
  108.     local source = fs.open(input,"r")
  109.     local code = {}
  110.     local line = source.readLine()
  111.     while line do
  112.       code[#code+1] = line
  113.       line = source.readLine()
  114.     end
  115.     source.close()
  116.     local hexdump = ""
  117.     print("Compiling code...")
  118.     for i = 1, #code do
  119.         if(#code[i]:gsub("%s+","") ~= 0 and not code[i]:find(keyword_label) and not code[i]:find(keyword_var))then
  120.             -- Check if code references label or variable
  121.             local op  = string.upper(code[i]:gsub("%s+",""):sub(1,3))
  122.             local vtype = code[i]:gsub("%s+",""):sub(4,4)
  123.             local val = code[i]:gsub("%s+",""):sub(4,#code[i])
  124.             if(val:sub(1,1) == "#")then val = val:sub(2,#val) end
  125.  
  126.             if(not _G.ASM._HEXENCODE[op])then error("Syntax error line " .. online .. ": " .. code[i]) end
  127.  
  128.             if(vars[val] ~= nil)then
  129.                 if(_G.ASM._HEXENCODE[op]['REL'] ~= nil)then
  130.                     -- No variable branching!
  131.                     error("Syntax error line " .. online .. ": " .. code[i])
  132.                 end
  133.                 if(vtype == "#")then
  134.                     code[i] = op .. " #$" .. vars[val]
  135.                     --print(code[i])
  136.                 else
  137.                     -- Direct index
  138.                     if(not tonumber(vars[val]))then error("Syntax error line " .. online .. ": " .. code[i]) end
  139.                     code[i] = op .. " $" .. vars[val]
  140.                     --print(code[i])
  141.                 end
  142.             elseif(labels[val] ~= nil)then
  143.                 -- Insert for relative branching
  144.                 local bytediff = 0 
  145.                 if(_G.ASM._HEXENCODE[op]['REL'] ~= nil)then
  146.                     -- Jump difference
  147.                     local difference = labels[val] - (codeline+1)
  148.                     if(difference < 0)then
  149.                         local bytes = 1
  150.                         for i = labels[val], codeline+1 do
  151.                             bytes = bytes + linebytes[i]
  152.                         end
  153.                         bytediff = -bytes
  154.                         print(bytes)
  155.                         -- Subtract the amount of bytes taken by branch
  156.                         bytediff = 256 + bytediff
  157.                     else
  158.                         for i = codeline+2, codeline+difference-1  do
  159.                             bytediff = bytediff + linebytes[i]
  160.                         end
  161.                        
  162.                     end
  163.                     bytediff = toHex(bytediff)
  164.                     -- Insert branch difference into code
  165.                     code[i] = op .. " *+" .. bytediff
  166.                     --print(code[i])
  167.                 else
  168.                     -- Insert for jumping
  169.                     local newBase = toHex(tonumber(programstart,16) + labels[val]-1)
  170.                     if(#newBase < 4)then newBase = string.rep("0",4-#newBase) .. newBase end
  171.                     code[i] = op .. " $" .. newBase
  172.                     --print(code[i])
  173.                 end
  174.             end
  175.             local hex = AssembleHEX(code[i],online)
  176.             hexdump = hexdump .. hex
  177.             codeline = codeline + 1
  178.         end
  179.         online = online + 1
  180.     end
  181.     -- Compile hex to bytes
  182.     local hexbytes = ""
  183.     local _hexdump = hexdump
  184.     hexdump = hexdump:gsub("%s+","")
  185.     if(#hexdump > 2)then
  186.         for i=1, #hexdump, 2 do
  187.             hexbytes = hexbytes .. string.char(tonumber(hexdump:sub(i,i+1),16))
  188.         end
  189.     else
  190.         hexbytes[1] = string.char(tonumber(hexdump,16))
  191.     end
  192.  
  193.     print("Hex Compiled: " .. _hexdump)
  194.     --local f = fs.open(output,"w")
  195.     --f.writeLine(":> HEX Source: " .. hexdump)
  196.     --f.writeLine(hexbytes)
  197.     --f.close()
  198.     print("Hex outputed to: " .. output)
  199.     print("Done. ")
  200. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement