Initial commit
[jwcc.git] / jwcc.lua
CommitLineData
933e60e3
JW
1#!/usr/bin/env lua
2require"lib/tokenizer/default"
3require"lib/parser/default"
4require"lib/deparser"
5require"lib/backend/default"
6
7local input,finaloutput,mode,cppopts
8mode = {"preprocess","compile","assemble"}
9cppopts = "-P -nostdinc -isystem include -traditional-cpp "
10local argn = 1
11while arg[argn] do
12 if arg[argn]:sub(1,1) == "-" then
13 -- parse as an option
14 local rem = arg[argn]:sub(2)
15 while true do
16 if rem:sub(1,1) == "E" then -- preprocess only
17 mode = {"preprocess"}
18 elseif rem:sub(1,1) == "S" then -- compile only
19 mode = {"preprocess","compile"}
20 elseif rem:sub(1,1) == "c" then -- compile and assemble
21 mode = {"preprocess","compile","assemble"}
22 elseif rem:sub(1,1) == "o" then -- output
23 if finaloutput then
24 print("jwcc: -o can only be specified once")
25 os.exit(254)
26 end
27 if rem:len() > 1 then
28 finaloutput = rem:sub(2)
29 break
30 else
31 if not arg[argn+1] then
32 print("jwcc: -o requires an option")
33 os.exit(254)
34 end
35 finaloutput = arg[argn+1]
36 argn = argn + 1
37 end
38 elseif rem:sub(1,1) == "D" then
39 if rem:lem() > 1 then
40 cppopts = cppopts .. "-D "..rem:sub(2).." "
41 break
42 else
43 if not arg[argn+1] then
44 print("jwcc: -D requires an option")
45 os.exit(254)
46 end
47 cppopts = cppopts .. "-D "..arg[argn+1].." "
48 argn = argn + 1
49 end
50 elseif rem:sub(1,1) == "I" then
51 if rem:lem() > 1 then
52 cppopts = cppopts .. "-I "..rem:sub(2).." "
53 break
54 else
55 if not arg[argn+1] then
56 print("jwcc: -I requires an option")
57 os.exit(254)
58 end
59 cppopts = cppopts .. "-I "..arg[argn+1].." "
60 argn = argn + 1
61 end
62 elseif rem:len() == 0 then
63 break
64 else
65 print("jwcc: unknown option \""..rem:sub(1,1).."\"")
66 os.exit(254)
67 end
68 rem = rem:sub(2)
69 end
70 else
71 if input then
72 print("jwcc: input can only be specified once")
73 os.exit(254)
74 end
75 input = arg[argn]
76 end
77 argn = argn + 1
78end
79
80if not input then
81 print("jwcc: no input specified")
82 os.exit(254)
83end
84
85local output
86for k,v in pairs(mode) do
87 if v == "preprocess" then
88 if input:match("%.c$") then
89 if not mode[k+1] and finaloutput then
90 output = finaloutput
91 else
92 output = input:gsub("%.c$", ".i")
93 end
94 -- do preprocessing
95 if os.execute("cpp "..cppopts.." "..input.." "..output) ~= 0 then
96 os.exit(1)
97 end
98 input = output
99 end
100 elseif v == "compile" then
101 if input:match("%.i$") then
102 if not mode[k+1] and finaloutput then
103 output = finaloutput
104 else
105 output = input:gsub("%.i$", ".s")
106 end
107 local f = assert(io.open(input, "r"))
108 local insrc = f:read("*all")
109 f:close()
110 tokenlist = tokenize(insrc)
111 parsetree = parse(tokenlist)
112 --deparse(parsetree)
113 if backend(parsetree, output) then
114 os.exit(1)
115 end
116 input = output
117 end
118 elseif v == "assemble" then
119 if input:match("%.s$") then
120 if not mode[k+1] and finaloutput then
121 output = finaloutput
122 else
123 output = input:gsub("%.o$", ".s")
124 end
125 if os.execute("blarg-elf-as --fatal-warnings -o "..output.." "..input) ~= 0 then
126 os.exit(1)
127 end
128 input = output
129 end
130 end
131end
This page took 0.029564 seconds and 4 git commands to generate.