9 /* #include dcpu16.h */
10 typedef unsigned short DCPU16_WORD
;
12 /* quick and dirty assembler for dcpu16 */
14 static const char * const src_id_
= "$Id$";
16 const char const out_filename_default_
[] = "a.out";
19 void usage_(char *prog
, unsigned int full
) {
20 FILE *f
= full
? stdout
: stderr
;
21 char *x
= strrchr(prog
, '/');
27 fprintf(f
, "%s -- \n\n",
30 fprintf(f
, "Usage: %s\n",
34 fprintf(f
, "\nOptions:\n"
35 "\t-h -- this screen\n"
36 "\t-o <file> -- output to <file> [default: %s]\n",
37 out_filename_default_
);
39 fprintf(f
, "\n%78s\n",
45 struct operand_
*next
;
50 struct instruction_
*next
;
53 struct operand_
*operands
;
55 unsigned int length
; /* words */
56 DCPU16_WORD instr_words
[];
59 /* buf must be 0-terminated */
61 int buf_tokenize_(char *buf
, struct instruction_
**next_instr
) {
62 const char const *sep
= " \t\n";
63 struct instruction_
*instr
= NULL
;
73 assert(next_instr
!= NULL
);
78 if ((x
= strchr(buf
, ';')) != NULL
)
80 /* kill leading whitespace */
81 buf
+= strspn(buf
, " \t\n");
82 /* kill trailing newlines */
83 if ((x
= strrchr(buf
, '\n')) != NULL
)
86 /* determine if first token is label, opcode, or we just have a blank line to ignore */
87 x
= strtok_r(buf
, sep
, &st
);
89 /* empty line? nothing to do here. */
93 /* labels end with :, otherwise its an opcode */
94 if ((y
= strrchr(x
, ':')) != NULL
) {
97 opcode
= strtok_r(NULL
, sep
, &st
);
107 instr
= calloc(1, sizeof *instr
);
109 fprintf(stderr
, "%s():%s\n", "malloc", strerror(errno
));
113 instr
->label
= label
;
114 instr
->opcode
= opcode
;
125 /* thish should grow buffer to fit huge linesh, but I jusht don't care right now, hic */
127 int parse_stream_(FILE *f
) {
128 struct instruction_
*instr
;
131 buf
[sizeof buf
- 1] = '\0';
133 while (fgets(buf
, sizeof buf
, f
)) {
134 if (buf
[sizeof buf
- 1] != '\0') {
135 fprintf(stderr
, "input buffer exhausted\n");
139 if (buf_tokenize_(buf
, &instr
)) {
140 fprintf(stderr
, "trouble tokenizing input\n");
147 printf("TRACE: new label '%s'\n", instr
->label
);
149 printf("TRACE: tokenized opcode:%s operands:",
151 for (o
= instr
->operands
; o
; o
= o
->next
) {
152 printf("%s%s", o
->operand
, o
->next
? ", " : "");
157 /* add to queue of instructions */
161 fprintf(stderr
, "%s():%s\n", "fgets", strerror(errno
));
165 fprintf(stderr
, "parsing aborted\n");
172 int main(int argc
, char *argv
[]) {
173 const char *out_filename
= NULL
;
176 while ( (c
= getopt(argc
, argv
, "ho:")) != EOF
) {
180 fprintf(stderr
, "Sorry, I can only write one file at a time.\n");
183 out_filename
= optarg
;
196 if (out_filename
== NULL
)
197 out_filename
= out_filename_default_
;
199 /* if filenames were specified, parse them instead of stdin */
201 while (argc
- optind
) {
202 FILE *f
= fopen(argv
[argc
- optind
], "r");
204 fprintf(stderr
, "%s('%s'):%s\n", "fopen", argv
[argc
- optind
], strerror(errno
));
216 parse_stream_(stdin
);