]>
Commit | Line | Data |
---|---|---|
933e60e3 JW |
1 | #!/usr/bin/env lua |
2 | require"lib/tokenizer/default" | |
3 | require"lib/parser/default" | |
4 | require"lib/deparser" | |
5 | require"lib/backend/default" | |
6 | ||
7 | local input,finaloutput,mode,cppopts | |
8 | mode = {"preprocess","compile","assemble"} | |
9 | cppopts = "-P -nostdinc -isystem include -traditional-cpp " | |
10 | local argn = 1 | |
11 | while 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 | |
78 | end | |
79 | ||
80 | if not input then | |
81 | print("jwcc: no input specified") | |
82 | os.exit(254) | |
83 | end | |
84 | ||
85 | local output | |
86 | for 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 | |
131 | end |