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
|
/*
* Prototype Processor aSsembler
*
* Computer architecture is by qubane
* Assembler is by nakidai and released in public domain
*/
#include <ctype.h>
#include <err.h>
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#define LINESZ 128
#define is(x, y) if (!strcmp((x), (y)))
char line[LINESZ];
void parsefile(const char *);
void emit(char inst)
{
printf("%04b\n", (int)inst);
}
void tolowers(char *s)
{
for (; *s; ++s)
*s = tolower(*s);
}
int parsereg(const char *name)
{
switch (*name)
{
case 'b': return 0;
case 'm': return 1;
case 'p': return 2;
default: return -1;
}
}
void parseline(char *line, const char *path, size_t n)
{
char *arg = strchr(line, ' '),
*end = strchr(line, '\n');
arg && (*arg = 0);
end && (*end = 0);
if (!*line)
return;
tolowers(line);
if (!arg++)
is (line, "ca") emit(8);
else is (line, "add") emit(9);
else is (line, "sub") emit(10);
else is (line, "and") emit(11);
else is (line, "or") emit(12);
else is (line, "xor") emit(13);
else is (line, "rd") emit(14);
else is (line, "wt") emit(15);
else is (line, ";") ;
else errx(1, "%s:%d: invalid instruction: %s", path, n, line);
else
is (line, "lda")
emit(atoi(arg));
else is (line, "movc")
if (tolowers(arg), parsereg(arg) < 0)
errx(1, "%s:%lu: invalid instruction: %s %s", path, n, line, arg);
else
emit(4 + parsereg(arg));
else is (line, "mov")
if (tolowers(arg), parsereg(arg) != 0)
errx(1, "%s:%lu: invalid instruction: %s %s", path, n, line, arg);
else
emit(7);
else is (line, "inc") parsefile(arg);
else is (line, ";");
else errx(1, "%s:%lu invalid instruction: %s %s", path, n, line, arg);
}
void parsefile(const char *file)
{
FILE *fp = fopen(file, "r");
size_t n = 0;
if (!fp)
err(1, "fopen(%s)", file);
while (fgets(line, sizeof(line), fp))
parseline(line, file, n++);
if (ferror(fp))
err(1, "fgets(%s)", file);
}
int main(int argc, char **argv)
{
if (!argv[1] || !*argv[1])
return fprintf(stderr, "usage: %s <filename>\n", *argv), 1;
parsefile(argv[1]);
}
|