-
Notifications
You must be signed in to change notification settings - Fork 1
/
m100-tokenize-main.c
79 lines (57 loc) · 2.04 KB
/
m100-tokenize-main.c
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
/* m100-tokenize-main.c Front end for Model 100 BASIC tokenizer
*
* This is just the frontend.
* For the actual tokenizer, see m100-tokenize.lex.
*/
/* Usage: m100-tokenize [ input.ba [ output.ba ] ]
* Examples:
(a) m100-tokenize FOO.DO FOO.BA
(b) m100-tokenize <FOO.DO >FOO.BA
(c) m100-tokenize FOO.DO | cat > FOO.BA
Note that (a) and (b) are identical, but (c) is slightly different.
If the output stream cannot be rewound, then the line pointers will
not be updated at the end. This does not matter for a genuine
Model T computer, but some emulators are known to be persnickety
and will refuse to load the file.
*/
int main(int argc, char *argv[]) {
++argv, --argc; /* skip over program name */
/* First arg (if any) is input file name */
yyin = (argc>0) ? fopen( argv[0], "r" ) : stdin;
if (yyin == NULL) { perror(argv[0]); exit(1); }
/* Second arg (if any) is output file name */
++argv, --argc;
yyout = (argc>0) ? fopen( argv[0], "w+" ) : stdout;
if (yyout == NULL) { perror(argv[0]); exit(1); }
while (yylex())
;
return 0;
}
int yywrap() {
return 1; /* Always only read one file */
}
int yyput(uint8_t c) {
/* Like putchar, but send to yyout instead of stdout */
fputc(c, yyout);
lastput = c; /* Save last char for handling EOF */
return 0;
}
int fixup_ptrs() {
/* At EOF, rewrite the line pointers in the output file so that each
line points to the next. This is not actually necessary. */
int offset = 0xA001; /* Offset into memory for start of program */
ptr[nlines++] = ftell(yyout); /* Pointer to final NULL byte */
if (fseek(yyout, 0L, SEEK_SET) != 0) {
perror("fseek");
fprintf(stderr,
"Warning: Could not rewind the output file to fixup pointers.\n"
"This will work on genuine hardware but not on some emulators.\n");
return 1;
}
for (int n=1; n < nlines; n++) {
fseek(yyout, ptr[n-1], SEEK_SET);
yyput( (offset + ptr[n]) & 0xFF);
yyput( (offset + ptr[n]) >> 8);
}
return 0;
}