forked from amber-smalltalk/amber
-
Notifications
You must be signed in to change notification settings - Fork 3
/
amberc
executable file
·185 lines (171 loc) · 6.7 KB
/
amberc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
#!/usr/bin/env node
var path = require('path');
var amberc = require('./amberc.js');
// get parameters passed to the command line script
// discard the first two parameters which are the node binary and the script name
var parameters = process.argv.slice(2);
// check if at least one parameter was passed to the script
if (1 > parameters.length) {
print_usage();
process.exit();
}
// Get Amber root directory from the location of this script so that
// we can find the st and js directories etc.
var amber_dir = path.normalize(path.join(path.dirname(process.argv[1]), '..'));
// Get default location of compiler.jar
var closure_jar = path.resolve(path.join(process.env['HOME'], 'compiler.jar'));
var compiler = new amberc.Compiler(amber_dir);
var configuration = handle_options(parameters, amber_dir);
compiler.main(configuration);
/**
* Process given program options and update defaults values.
* Followed by check_for_closure_compiler() and then collect_files().
*/
function handle_options(optionsArray, amber_dir) {
var programName = [];
var currentItem = optionsArray.shift();
var defaults = amberc.createDefaults(amber_dir);
while(undefined !== currentItem) {
switch(currentItem) {
case '-l':
defaults.load.push.apply(defaults.load, optionsArray.shift().split(','));
break;
case '-i':
defaults.init = optionsArray.shift();
break;
case '-m':
defaults.main = optionsArray.shift();
break;
case '-M':
defaults.mainfile = optionsArray.shift();
break;
case '-o':
defaults.closure = true;
defaults.closure_parts = true;
break;
case '-O':
defaults.closure = true;
defaults.closure_full = true;
break;
case '-A':
defaults.closure = true;
defaults.closure_options = defaults.closure_options + ' --compilation_level ADVANCED_OPTIMIZATIONS';
defaults.closure_full = true;
break;
case '-d':
defaults.deploy = true;
break;
case '-s':
defaults.suffix = optionsArray.shift();
defaults.suffix_used = defaults.suffix;
break;
case '-S':
defaults.loadsuffix = optionsArray.shift();
defaults.suffix_used = defaults.suffix;
break;
case '-h':
case '--help':
case '?':
this.usage();
break;
default:
var fileSuffix = path.extname(currentItem);
switch (fileSuffix) {
case '.st':
defaults.stFiles.push(currentItem);
break;
case '.js':
defaults.jsFiles.push(currentItem);
break;
default:
// Will end up being the last non js/st argument
programName.push(currentItem);
break;
};
};
currentItem = optionsArray.shift();
}
if(1 < programName.length) {
throw new Error('More than one name for ProgramName given: ' + programName);
} else {
defaults.program = programName[0];
}
return defaults;
};
// print available flags
function print_usage() {
console.log('Usage: amberc [-l lib1,lib2...] [-i init_file] [-m main_class] [-M main_file]');
console.log(' [-o] [-O|-A] [-d] [-s suffix] [-S suffix] [file1 [file2 ...]] [Program]');
console.log('');
console.log(' amberc compiles Amber files - either separately or into a complete runnable');
console.log(' program. If no .st files are listed only a linking stage is performed.');
console.log(' Files listed will be handled using the following rules:');
console.log('');
console.log(' *.js');
console.log(' Files are linked (concatenated) in listed order.');
console.log(' If not found we look in $AMBER/js/');
console.log('');
console.log(' *.st');
console.log(' Files are compiled into .js files before concatenation.');
console.log(' If not found we look in $AMBER/st/.');
console.log('');
console.log(' NOTE: Each .st file is currently considered to be a fileout of a single class');
console.log(' category of the same name as the file!');
console.log('');
console.log(' If no <Program> is specified each given .st file will be compiled into');
console.log(' a matching .js file. Otherwise a <Program>.js file is linked together based on');
console.log(' the given options:');
console.log(' -l library1,library2');
console.log(' Add listed JavaScript libraries in listed order.');
console.log(' Libraries are not separated by spaces or end with .js.');
console.log('');
console.log(' -i init_file');
console.log(' Add library initializer <init_file> instead of default $AMBER/js/init.js ');
console.log('');
console.log(' -m main_class');
console.log(' Add a call to the class method main_class>>main at the end of <Program>.');
console.log('');
console.log(' -M main_file');
console.log(' Add <main_file> at the end of <Program.js> acting as #main.');
console.log('');
console.log(' -o');
console.log(' Optimize each .js file using the Google closure compiler.');
console.log(' Using Closure compiler found at ~/compiler.jar');
console.log('');
console.log(' -O');
console.log(' Optimize final <Program>.js using the Google closure compiler.');
console.log(' Using Closure compiler found at ~/compiler.jar');
console.log('');
console.log(' -A Same as -O but use --compilation_level ADVANCED_OPTIMIZATIONS');
console.log('');
console.log(' -d');
console.log(' Additionally export code for deploy - stripped from source etc.');
console.log(' Uses suffix ".deploy.js" in addition to any explicit suffic set by -s.');
console.log('');
console.log(' -s suffix');
console.log(' Add <suffix> to compiled .js files. File.st is then compiled into');
console.log(' File.<suffix>.js.');
console.log('');
console.log(' -S suffix');
console.log(' Use <suffix> for all libraries accessed using -l. This makes it possible');
console.log(' to have multiple flavors of Amber and libraries in the same place.');
console.log('');
console.log('');
console.log(' Example invocations:');
console.log('');
console.log(' Just compile Kernel-Objects.st to Kernel-Objects.js:');
console.log('');
console.log(' amberc Kernel-Objects.st');
console.log('');
console.log(' Compile Hello.st to Hello.js and create complete program called Program.js.');
console.log(' Additionally add a call to the class method Hello>>main:');
console.log('');
console.log(' amberc -m Hello Hello.st Program');
console.log('');
console.log(' Compile Cat1.st and Cat2.st files into corresponding .js files.');
console.log(' Link them with myboot.js and myKernel.js and add myinit.js as custom');
console.log(' initializer file. Add main.js last which contains the startup code');
console.log(' and merge everything into a complete program named Program.js:');
console.log('');
console.log(' amberc -M main.js -i myinit.js myboot.js myKernel.js Cat1.st Cat2.st Program');
};