1 //
2 // Copyright (c) 2006, Brian Frank and Andy Frank
3 // Licensed under the Academic Free License version 3.0
4 //
5 // History:
6 // 15 Sep 05 Brian Frank Creation
7 // 3 Jun 06 Brian Frank Ported from Java to Fan - Megan's b-day
8 //
9
10 **
11 ** Main is the main entry point for the Fan compiler. It handles
12 ** all the argument processing and misc commands like help, version,
13 **
14 class Main
15 {
16
17 //////////////////////////////////////////////////////////////////////////
18 // Run
19 //////////////////////////////////////////////////////////////////////////
20
21 **
22 ** Main entry point for compiler.
23 **
24 Int run(Str[] args)
25 {
26 t1 := Duration.now
27 success := true
28
29 // process args
30 if (!parseArgs(args)) return 0
31
32 // process each directory specified
33 try
34 {
35 compile
36 }
37 catch (CompilerErr err)
38 {
39 // all errors should already be logged by Compiler
40 success = false;
41 }
42 catch (Err err)
43 {
44 log.compilerErr(CompilerErr.make("Internal compiler error", null, err));
45 err.trace
46 success = false;
47 }
48
49 t2 := Duration.now
50 if (success)
51 {
52 println("SUCCESS (" + (t2-t1).toMillis + "ms)")
53 return 0
54 }
55 else
56 {
57 println("FAILED (" + (t2-t1).toMillis + "ms)")
58 return -1
59 }
60 }
61
62 **
63 ** Process command line args and return false if we should exit.
64 **
65 Bool parseArgs(Str[] args)
66 {
67 if (args.isEmpty)
68 {
69 help
70 return false
71 }
72
73 for (i:=0; i<args.size; ++i)
74 {
75 a := args[i]
76 if (a.isEmpty) continue
77 if (a == "-help" || a == "-h" || a == "-?")
78 {
79 help
80 return false
81 }
82 else if (a == "-version")
83 {
84 version
85 return false
86 }
87 else if (a == "-d")
88 {
89 if (i+1 >= args.size)
90 {
91 println("ERROR: must specified dir with -d option")
92 return false
93 }
94 outDir = File.make(args[++i].toUri).normalize
95 }
96 else if (a == "-src")
97 {
98 includeSrc = true
99 }
100 else if (a == "-doc")
101 {
102 includeDoc = true
103 }
104 else if (a == "-v")
105 {
106 log.level = LogLevel.verbose
107 }
108 else if (a == "-silent")
109 {
110 log.level = LogLevel.silent
111 }
112 else if (a[0] == '-')
113 {
114 println("WARNING: Unknown option " + a)
115 }
116 else
117 {
118 if (podName == null)
119 podName = a
120 else
121 srcDirs.add(File.make(a.toUri))
122 }
123 }
124
125 // if no dirs were specified, assume current dir
126 if (podName == null || srcDirs.isEmpty)
127 {
128 println("ERROR: not enough arguments")
129 help
130 return false
131 }
132
133 return true
134 }
135
136 **
137 ** Dump help usage.
138 **
139 Void help()
140 {
141 println("Fan Compiler (the one written in Fan itself)")
142 println("Usage:")
143 println(" ffanc [options] <podName> <srcDir>*")
144 println("Options:")
145 println(" -help, -h, -? print usage help")
146 println(" -version print version information")
147 println(" -d <dir> output directory for pod file")
148 println(" -doc include fandoc in pod")
149 println(" -src include source code in pod")
150 println(" -v verbose mode (more logging)")
151 println(" -silent silent mode (no logging)")
152 }
153
154 **
155 ** Dump version.
156 **
157 Void version()
158 {
159 println("Fan Compiler - Version ${type.pod.version}")
160 println("Copyright (c) 2006, Brian Frank and Andy Frank")
161 println("Licensed under the Academic Free License version 3.0")
162 }
163
164 **
165 ** Compile using current configuration
166 **
167 Void compile()
168 {
169 input := CompilerInput.make
170 input.podName = podName
171 input.log = log
172 input.mode = CompilerInputMode.file
173 input.homeDir = srcDirs.first.parent
174 input.srcDirs = srcDirs
175 input.includeDoc = includeDoc
176 input.includeSrc = includeSrc
177 input.output = CompilerOutputMode.podFile
178 if (outDir != null) input.outDir = outDir
179
180 Compiler.make(input).compile
181 }
182
183 **
184 ** Compile the script file into a transient pod
185 **
186 static Pod compileScript(File file)
187 {
188 input := CompilerInput.make
189 input.log.level = LogLevel.error
190 input.podName = "script_$file.basename"
191 input.isScript = true
192 input.srcStr = file.readAllStr
193 input.srcStrLocation = Location.makeFile(file)
194 input.mode = CompilerInputMode.str
195 input.output = CompilerOutputMode.transientPod
196 return Compiler.make(input).compile.transientPod
197 }
198
199 //////////////////////////////////////////////////////////////////////////
200 // Utils
201 //////////////////////////////////////////////////////////////////////////
202
203 Void println(Obj s)
204 {
205 log.printLine(s)
206 }
207
208 //////////////////////////////////////////////////////////////////////////
209 // Main
210 //////////////////////////////////////////////////////////////////////////
211
212 static Void main()
213 {
214 Sys.exit(make.run(Sys.args))
215 }
216
217 //////////////////////////////////////////////////////////////////////////
218 // Fields
219 //////////////////////////////////////////////////////////////////////////
220
221 Str podName
222 File[] srcDirs := File[,] // directories to build
223 File outDir := null // -d output directory
224 CompilerLog log := CompilerLog.make // logging, -v verbose output
225 Bool includeDoc := false // include fandoc in output pod
226 Bool includeSrc := false // include source code in output pod
227
228 }
2 // Copyright (c) 2006, Brian Frank and Andy Frank
3 // Licensed under the Academic Free License version 3.0
4 //
5 // History:
6 // 15 Sep 05 Brian Frank Creation
7 // 3 Jun 06 Brian Frank Ported from Java to Fan - Megan's b-day
8 //
9
10 **
11 ** Main is the main entry point for the Fan compiler. It handles
12 ** all the argument processing and misc commands like help, version,
13 **
14 class Main
15 {
16
17 //////////////////////////////////////////////////////////////////////////
18 // Run
19 //////////////////////////////////////////////////////////////////////////
20
21 **
22 ** Main entry point for compiler.
23 **
24 Int run(Str[] args)
25 {
26 t1 := Duration.now
27 success := true
28
29 // process args
30 if (!parseArgs(args)) return 0
31
32 // process each directory specified
33 try
34 {
35 compile
36 }
37 catch (CompilerErr err)
38 {
39 // all errors should already be logged by Compiler
40 success = false;
41 }
42 catch (Err err)
43 {
44 log.compilerErr(CompilerErr.make("Internal compiler error", null, err));
45 err.trace
46 success = false;
47 }
48
49 t2 := Duration.now
50 if (success)
51 {
52 println("SUCCESS (" + (t2-t1).toMillis + "ms)")
53 return 0
54 }
55 else
56 {
57 println("FAILED (" + (t2-t1).toMillis + "ms)")
58 return -1
59 }
60 }
61
62 **
63 ** Process command line args and return false if we should exit.
64 **
65 Bool parseArgs(Str[] args)
66 {
67 if (args.isEmpty)
68 {
69 help
70 return false
71 }
72
73 for (i:=0; i<args.size; ++i)
74 {
75 a := args[i]
76 if (a.isEmpty) continue
77 if (a == "-help" || a == "-h" || a == "-?")
78 {
79 help
80 return false
81 }
82 else if (a == "-version")
83 {
84 version
85 return false
86 }
87 else if (a == "-d")
88 {
89 if (i+1 >= args.size)
90 {
91 println("ERROR: must specified dir with -d option")
92 return false
93 }
94 outDir = File.make(args[++i].toUri).normalize
95 }
96 else if (a == "-src")
97 {
98 includeSrc = true
99 }
100 else if (a == "-doc")
101 {
102 includeDoc = true
103 }
104 else if (a == "-v")
105 {
106 log.level = LogLevel.verbose
107 }
108 else if (a == "-silent")
109 {
110 log.level = LogLevel.silent
111 }
112 else if (a[0] == '-')
113 {
114 println("WARNING: Unknown option " + a)
115 }
116 else
117 {
118 if (podName == null)
119 podName = a
120 else
121 srcDirs.add(File.make(a.toUri))
122 }
123 }
124
125 // if no dirs were specified, assume current dir
126 if (podName == null || srcDirs.isEmpty)
127 {
128 println("ERROR: not enough arguments")
129 help
130 return false
131 }
132
133 return true
134 }
135
136 **
137 ** Dump help usage.
138 **
139 Void help()
140 {
141 println("Fan Compiler (the one written in Fan itself)")
142 println("Usage:")
143 println(" ffanc [options] <podName> <srcDir>*")
144 println("Options:")
145 println(" -help, -h, -? print usage help")
146 println(" -version print version information")
147 println(" -d <dir> output directory for pod file")
148 println(" -doc include fandoc in pod")
149 println(" -src include source code in pod")
150 println(" -v verbose mode (more logging)")
151 println(" -silent silent mode (no logging)")
152 }
153
154 **
155 ** Dump version.
156 **
157 Void version()
158 {
159 println("Fan Compiler - Version ${type.pod.version}")
160 println("Copyright (c) 2006, Brian Frank and Andy Frank")
161 println("Licensed under the Academic Free License version 3.0")
162 }
163
164 **
165 ** Compile using current configuration
166 **
167 Void compile()
168 {
169 input := CompilerInput.make
170 input.podName = podName
171 input.log = log
172 input.mode = CompilerInputMode.file
173 input.homeDir = srcDirs.first.parent
174 input.srcDirs = srcDirs
175 input.includeDoc = includeDoc
176 input.includeSrc = includeSrc
177 input.output = CompilerOutputMode.podFile
178 if (outDir != null) input.outDir = outDir
179
180 Compiler.make(input).compile
181 }
182
183 **
184 ** Compile the script file into a transient pod
185 **
186 static Pod compileScript(File file)
187 {
188 input := CompilerInput.make
189 input.log.level = LogLevel.error
190 input.podName = "script_$file.basename"
191 input.isScript = true
192 input.srcStr = file.readAllStr
193 input.srcStrLocation = Location.makeFile(file)
194 input.mode = CompilerInputMode.str
195 input.output = CompilerOutputMode.transientPod
196 return Compiler.make(input).compile.transientPod
197 }
198
199 //////////////////////////////////////////////////////////////////////////
200 // Utils
201 //////////////////////////////////////////////////////////////////////////
202
203 Void println(Obj s)
204 {
205 log.printLine(s)
206 }
207
208 //////////////////////////////////////////////////////////////////////////
209 // Main
210 //////////////////////////////////////////////////////////////////////////
211
212 static Void main()
213 {
214 Sys.exit(make.run(Sys.args))
215 }
216
217 //////////////////////////////////////////////////////////////////////////
218 // Fields
219 //////////////////////////////////////////////////////////////////////////
220
221 Str podName
222 File[] srcDirs := File[,] // directories to build
223 File outDir := null // -d output directory
224 CompilerLog log := CompilerLog.make // logging, -v verbose output
225 Bool includeDoc := false // include fandoc in output pod
226 Bool includeSrc := false // include source code in output pod
227
228 }