-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtestscript.d
More file actions
242 lines (196 loc) · 4.96 KB
/
testscript.d
File metadata and controls
242 lines (196 loc) · 4.96 KB
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
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
/* Digital Mars DMDScript source code.
* Copyright (c) 2000-2002 by Chromium Communications
* D version Copyright (c) 2004-2010 by Digital Mars
* Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
* written by Walter Bright
* http://www.digitalmars.com
*
* D2 port by Dmitry Olshansky
*
* DMDScript is implemented in the D Programming Language,
* http://www.digitalmars.com/d/
*
* For a C++ implementation of DMDScript, including COM support, see
* http://www.digitalmars.com/dscript/cppscript.html
*/
module testscript;
import std.path;
import std.file;
import std.stdio;
import std.exception;
import std.c.stdlib;
import core.memory;
import dmdscript.script;
import dmdscript.program;
import dmdscript.errmsgs;
enum
{
EXITCODE_INIT_ERROR = 1,
EXITCODE_INVALID_ARGS = 2,
EXITCODE_RUNTIME_ERROR = 3,
}
//Ehm, well, this fools VisualD, and of little convinience anyway
/*version (Windows)
{
pragma(lib, "dmdscript");
}*/
/**************************************************
Usage:
ds
will run test.ds
ds foo
will run foo.ds
ds foo.js
will run foo.js
ds foo1 foo2 foo.bar
will run foo1.ds, foo2.ds, foo.bar
The -iinc flag will prefix the source files with the contents of file inc.
There can be multiple -i's. The include list is reset to empty any time
a new -i is encountered that is not preceded by a -i.
ds -iinc foo
will prefix foo.ds with inc
ds -iinc1 -iinc2 foo bar
will prefix foo.ds with inc1+inc2, and will prefix bar.ds
with inc1+inc2
ds -iinc1 -iinc2 foo -iinc3 bar
will prefix foo.ds with inc1+inc2, and will prefix bar.ds
with inc3
ds -iinc1 -iinc2 foo -i bar
will prefix foo.ds with inc1+inc2, and will prefix bar.ds
with nothing
*/
int main(string[] args)
{
uint errors = 0;
string[] includes;
SrcFile[] srcfiles;
int result;
bool verbose;
bool print;
ErrInfo errinfo;
// GC.disable();
//
// dmdscript.opcodes.IR.trace=true;
if(args.length == 1)
stderr.writefln(dmdscript.script.banner());
for (size_t i = 1; i < args.length; i++)
{ string p = args[i];
if (p[0] == '-')
{
switch (p[1])
{
case 'i':
if (p[2])
includes ~= p[2 .. $];
break;
case 'v':
verbose = 1;
break;
case 'p':
print = 1;
break;
default:
writefln(errmsgtbl[ERR_BAD_SWITCH],p);
errors++;
break;
}
}
else
{
srcfiles ~= new SrcFile(p, includes);
includes = null;
}
}
if (errors)
return EXITCODE_INVALID_ARGS;
if (srcfiles.length == 0)
{
srcfiles ~= new SrcFile("test", null);
}
//stderr.writefln("%d source files", srcfiles.length);
// Read files, parse them, execute them
foreach (SrcFile m; srcfiles)
{
if (verbose)
writefln("read %s:", m.srcfile);
m.read();
if (verbose)
writefln("compile %s:", m.srcfile);
m.compile();
if (print) m.printfunc;
if (verbose)
writefln("execute %s:", m.srcfile);
//m.printfunc;
m.execute();
}
return EXIT_SUCCESS;
}
class SrcFile
{
string srcfile;
string[] includes;
Program program;
char[] buffer;
this(string srcfilename, string[] includes)
{
/* DMDScript source files default to a '.ds' extension
*/
srcfile = std.path.defaultExtension(srcfilename, "ds");
this.includes = includes;
}
void read()
{
/* Read the source file, prepend the include files,
* and put it all in buffer[]. Allocate an extra byte
* to buffer[] and terminate it with a 0x1A.
* (If the 0x1A isn't at the end, the lexer will put
* one there, forcing an extra copy to be made of the
* source text.)
*/
//writef("read file '%s'\n",srcfile);
// Read the includes[] files
size_t i;
void[] buf;
ulong len;
len = std.file.getSize(srcfile);
foreach (string filename; includes)
{
len += std.file.getSize(filename);
}
len++; // leave room for sentinal
assert(len < uint.max);
// Prefix the includes[] files
int sz = cast(int)len;
buffer = new char[sz];
foreach (string filename; includes)
{
buf = std.file.read(filename);
buffer[i .. i + buf.length] = cast(string)buf[];
i += buf.length;
}
buf = std.file.read(srcfile);
buffer[i .. i + buf.length] = cast(string)buf[];
i += buf.length;
buffer[i] = 0x1A; // ending sentinal
i++;
assert(i == len);
}
void compile()
{
/* Create a DMDScript program, and compile our text buffer.
*/
program = new Program();
program.compile(srcfile, assumeUnique(buffer), null);
}
void execute()
{
/* Execute the resulting program.
*/
program.execute(null);
}
void printfunc()
{
program.printfunc;
}
}