#!/usr/bin/env lua require"lib/tokenizer/default" require"lib/parser/default" require"lib/deparser" require"lib/backend/default" local input,finaloutput,mode,cppopts mode = {"preprocess","compile","assemble"} cppopts = "-P -nostdinc -isystem include -traditional-cpp " local argn = 1 while arg[argn] do if arg[argn]:sub(1,1) == "-" then -- parse as an option local rem = arg[argn]:sub(2) while true do if rem:sub(1,1) == "E" then -- preprocess only mode = {"preprocess"} elseif rem:sub(1,1) == "S" then -- compile only mode = {"preprocess","compile"} elseif rem:sub(1,1) == "c" then -- compile and assemble mode = {"preprocess","compile","assemble"} elseif rem:sub(1,1) == "o" then -- output if finaloutput then print("jwcc: -o can only be specified once") os.exit(254) end if rem:len() > 1 then finaloutput = rem:sub(2) break else if not arg[argn+1] then print("jwcc: -o requires an option") os.exit(254) end finaloutput = arg[argn+1] argn = argn + 1 end elseif rem:sub(1,1) == "D" then if rem:lem() > 1 then cppopts = cppopts .. "-D "..rem:sub(2).." " break else if not arg[argn+1] then print("jwcc: -D requires an option") os.exit(254) end cppopts = cppopts .. "-D "..arg[argn+1].." " argn = argn + 1 end elseif rem:sub(1,1) == "I" then if rem:lem() > 1 then cppopts = cppopts .. "-I "..rem:sub(2).." " break else if not arg[argn+1] then print("jwcc: -I requires an option") os.exit(254) end cppopts = cppopts .. "-I "..arg[argn+1].." " argn = argn + 1 end elseif rem:len() == 0 then break else print("jwcc: unknown option \""..rem:sub(1,1).."\"") os.exit(254) end rem = rem:sub(2) end else if input then print("jwcc: input can only be specified once") os.exit(254) end input = arg[argn] end argn = argn + 1 end if not input then print("jwcc: no input specified") os.exit(254) end local output for k,v in pairs(mode) do if v == "preprocess" then if input:match("%.c$") then if not mode[k+1] and finaloutput then output = finaloutput else output = input:gsub("%.c$", ".i") end -- do preprocessing if os.execute("cpp "..cppopts.." "..input.." "..output) ~= 0 then os.exit(1) end input = output end elseif v == "compile" then if input:match("%.i$") then if not mode[k+1] and finaloutput then output = finaloutput else output = input:gsub("%.i$", ".s") end local f = assert(io.open(input, "r")) local insrc = f:read("*all") f:close() tokenlist = tokenize(insrc) parsetree = parse(tokenlist) --deparse(parsetree) if backend(parsetree, output) then os.exit(1) end input = output end elseif v == "assemble" then if input:match("%.s$") then if not mode[k+1] and finaloutput then output = finaloutput else output = input:gsub("%.o$", ".s") end if os.execute("blarg-elf-as --fatal-warnings -o "..output.." "..input) ~= 0 then os.exit(1) end input = output end end end