Initial commit
[jwcc.git] / jwcc.lua
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
This page took 0.023998 seconds and 4 git commands to generate.