Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- function AssembleASM(input,output)
- if(not fs.exists(input))then error("File doesnt exist: " .. input) end
- if(fs.exists(output))then error("File exists: " .. output) end
- local labels = {}
- local vars = {}
- local keyword_var = "define"
- local keyword_label = ":"
- local online = 1
- local codeline = 0
- local programstart = 600
- print("Reading file...")
- -- Safer to read file first, then compile as the fs hook is closed, and they is no risk of data loss.
- local source = fs.open(input,"r")
- local code = {}
- local line = source.readLine()
- while line do
- code[#code+1] = line
- line = source.readLine()
- end
- source.close()
- -- Compile Variables and labels, check for syntax errors
- print("Initializing...")
- for i = 1, #code do
- -- Handle variables
- if(#code[i]:gsub("%s+","") ~= 0)then
- codeline = codeline + 1
- end
- if(code[i]:find(keyword_var))then
- local val = str_shearWord(code[i],keyword_var)
- local nargs = {}
- -- Take spaces out of string, then split it into 2 variables
- val = val:gsub("%s+", "")
- -- Split string by $
- for word in string.gmatch(val, '([^$]+)') do
- table.insert(nargs, word)
- end
- if(#nargs > 2)then error("Syntax error line " .. online .. ": " .. code[i]) end
- -- Convert ASCII to hex
- if(tonumber(nargs[2]) == nil)then
- nargs[2] = string.byte(nargs[2])
- end
- -- if(_G.ASM._HEXENCODE[string.upper(nargs[1])])then error("Syntax error line " .. online .. ": " .. code[i]) end
- vars[nargs[1]] = nargs[2]
- -- print(nargs[1] .. ": " .. vars[nargs[1]])
- end
- -- Handle labels
- if(code[i]:find(keyword_label))then
- local val = code[i]:gsub("%s+","")
- local nargs = {}
- for word in string.gmatch(val, '([^:]+)') do
- table.insert(nargs, word)
- end
- if(#nargs > 1 or nargs == nil)then
- error("Syntax error line " .. online .. ": " .. code[i])
- end
- labels[nargs[1]] = codeline
- print(nargs[1] .. ": " .. labels[nargs[1]])
- -- print(nargs[1] .. ": " .. labels[nargs[1]])
- end
- online = online + 1
- end
- -- Get Bytes Per line
- codeline = 0
- online = 1
- linebytes = {}
- local code_backup = code -- LUA bug where this variable acts like a pointer and still writes to code, screw lua.
- print("Getting Bytes...")
- for i = 1, #code_backup do
- if(#code_backup[i]:gsub("%s+","") ~= 0 and not code_backup[i]:find(keyword_label) and not code_backup[i]:find(keyword_var))then
- local op = string.upper(code_backup[i]:gsub("%s+",""):sub(1,3))
- local vtype = code_backup[i]:gsub("%s+",""):sub(4,4)
- local val = code_backup[i]:gsub("%s+",""):sub(4,#code_backup[i])
- if(val:sub(1,1) == "#")then val = val:sub(2,#val) end
- if(not _G.ASM._HEXENCODE[op])then error("Syntax error line " .. online .. ": " .. code_backup[i]) end
- if(vars[val] ~= nil)then
- if(_G.ASM._HEXENCODE[op]['REL'] ~= nil)then
- error("Syntax error line " .. online .. ": " .. code_backup[i])
- end
- if(vtype == "#")then
- code_backup[i] = op .. " #$" .. vars[val]
- else
- if(not tonumber(vars[val]))then error("Syntax error line " .. online .. ": " .. code_backup[i]) end
- code_backup[i] = op .. " $" .. vars[val]
- end
- elseif(labels[val] ~= nil)then
- if(_G.ASM._HEXENCODE[op]['REL'] ~= nil)then
- code_backup[i] = op .. " *+" .. "00"
- else
- local newBase = toHex(tonumber(programstart,16) + labels[val]-1)
- if(#newBase < 4)then newBase = string.rep("0",4-#newBase) .. newBase end
- code_backup[i] = op .. " $" .. newBase
- end
- end
- codeline = codeline + 1
- local op, otype, num = procInstructionType(code_backup[i],false,false)
- if(lineB == "op")then error("Syntax error line " .. online .. ": " .. code_backup[i]) end
- local lineB = getInstuctionBytes(op,otype)
- if(lineB == "err")then error("Syntax error line " .. online .. ": " .. code_backup[i]) end
- linebytes[#linebytes+1] = lineB
- end
- online = online + 1
- end
- -- Compile Code substitute variables and labels, check syntax
- -- Branch labels and jump labels, are controlled based on additions to the base program start
- codeline = 0
- online = 1
- local source = fs.open(input,"r")
- local code = {}
- local line = source.readLine()
- while line do
- code[#code+1] = line
- line = source.readLine()
- end
- source.close()
- local hexdump = ""
- print("Compiling code...")
- for i = 1, #code do
- if(#code[i]:gsub("%s+","") ~= 0 and not code[i]:find(keyword_label) and not code[i]:find(keyword_var))then
- -- Check if code references label or variable
- local op = string.upper(code[i]:gsub("%s+",""):sub(1,3))
- local vtype = code[i]:gsub("%s+",""):sub(4,4)
- local val = code[i]:gsub("%s+",""):sub(4,#code[i])
- if(val:sub(1,1) == "#")then val = val:sub(2,#val) end
- if(not _G.ASM._HEXENCODE[op])then error("Syntax error line " .. online .. ": " .. code[i]) end
- if(vars[val] ~= nil)then
- if(_G.ASM._HEXENCODE[op]['REL'] ~= nil)then
- -- No variable branching!
- error("Syntax error line " .. online .. ": " .. code[i])
- end
- if(vtype == "#")then
- code[i] = op .. " #$" .. vars[val]
- --print(code[i])
- else
- -- Direct index
- if(not tonumber(vars[val]))then error("Syntax error line " .. online .. ": " .. code[i]) end
- code[i] = op .. " $" .. vars[val]
- --print(code[i])
- end
- elseif(labels[val] ~= nil)then
- -- Insert for relative branching
- local bytediff = 0
- if(_G.ASM._HEXENCODE[op]['REL'] ~= nil)then
- -- Jump difference
- local difference = labels[val] - (codeline+1)
- if(difference < 0)then
- local bytes = 1
- for i = labels[val], codeline+1 do
- bytes = bytes + linebytes[i]
- end
- bytediff = -bytes
- print(bytes)
- -- Subtract the amount of bytes taken by branch
- bytediff = 256 + bytediff
- else
- for i = codeline+2, codeline+difference-1 do
- bytediff = bytediff + linebytes[i]
- end
- end
- bytediff = toHex(bytediff)
- -- Insert branch difference into code
- code[i] = op .. " *+" .. bytediff
- --print(code[i])
- else
- -- Insert for jumping
- local newBase = toHex(tonumber(programstart,16) + labels[val]-1)
- if(#newBase < 4)then newBase = string.rep("0",4-#newBase) .. newBase end
- code[i] = op .. " $" .. newBase
- --print(code[i])
- end
- end
- local hex = AssembleHEX(code[i],online)
- hexdump = hexdump .. hex
- codeline = codeline + 1
- end
- online = online + 1
- end
- -- Compile hex to bytes
- local hexbytes = ""
- local _hexdump = hexdump
- hexdump = hexdump:gsub("%s+","")
- if(#hexdump > 2)then
- for i=1, #hexdump, 2 do
- hexbytes = hexbytes .. string.char(tonumber(hexdump:sub(i,i+1),16))
- end
- else
- hexbytes[1] = string.char(tonumber(hexdump,16))
- end
- print("Hex Compiled: " .. _hexdump)
- --local f = fs.open(output,"w")
- --f.writeLine(":> HEX Source: " .. hexdump)
- --f.writeLine(hexbytes)
- --f.close()
- print("Hex outputed to: " .. output)
- print("Done. ")
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement