~grimmware/lc3

27239fbca2c69645e3b4d06a6cc0e2217a6b1479 — glenda 1 year, 2 months ago fc7102f
Bunch more work, got some semblance of token parsing...
2 files changed, 52 insertions(+), 30 deletions(-)

M asm.c
M tests/test.asm
M asm.c => asm.c +47 -28
@@ 13,8 13,7 @@ struct Inst {
	u16int	op;
	u16int	argc;
	u16int	mode;
	u16int	arg[3];
	char	*label;
	char*	arg[3];
};

typedef struct Symbol Symbol;


@@ 65,16 64,16 @@ syntaxerr(char* msg)
	exits("Syntax error");
}

void
newinst(void)
Inst
*newinst(u16int op)
{
	mem[memc] = emalloc(sizeof(Inst));
	mem[memc]->op = op;
	mem[memc]->argc = 0;
	for(int i = 0; i<3; i++)
		mem[memc]->arg[i] = 0;
	mem[memc]->mode = 0;
	mem[memc]->label = nil;
	return;
	return mem[memc];
}

int


@@ 92,6 91,7 @@ gettoken(char **t, char *l)
	*t = realloc(*t, sizeof(*t) * (len + 1));
	**t = 0;
	strncat(*t, l, len);
	print("%d:TOKEN:%s\n", lineno, *t);
	return len;
}



@@ 108,33 108,34 @@ findreg(char* name)
void
newnop(void)
{
	newinst();
	mem[memc]->op = OP_BR;
	mem[memc]->argc+=2;
	newinst(OP_BR);
	mem[memc]->argc+=2; // already initialized to 0;
}

/* FIXME: Should pass in string split into 3 args and then write something to parse a hex value when not a register.
void
newadd(char* arg[])
int
matchopcode(char* t)
{
	int i;

	newinst();
	mem[memc]->op = OP_ADD;
	for(int j = 0; j<2; j++){
		if((i = findreg(arg[j])) < 0)
			syntaxerr(smprint("%s is not a register"));
		mem[memc]->arg[j] = i;
	for(int i = 0; i < OP_COUNT; i++){
		if(!strcmp(t, opcode[i]))
			return i;
	}
	if((i = findreg(arg[j])) < 0)
		mem[memc]->arg[j] = PARSE IMM;
	
	return -1;
}
*/

void
newaddimm(char* dr, char* sr1, char* imm5)
parseargs(char* t, Inst* in)
{
	char* buf;
	buf = strtok(t, ",");
	if(buf == nil) return;
	in->arg[in->argc] = emalloc(strlen(buf) + 1);
	strcpy(in->arg[in->argc], buf);
	in->argc++;
	while((buf = strtok(nil, ",")) != nil && in->argc < 3){
		in->arg[in->argc] = emalloc(strlen(buf) + 1);
		strcpy(in->arg[in->argc], buf);
				in->argc++;}
	// FIXME should probably find some way to indicate arity errors here?
}

int


@@ 143,11 144,13 @@ parseline(char *l)
	int pos = 0;
	int c = 0;
	char *t = nil;
	int op = -1;
	Inst *inst;
	while(l[0] && pos < MAXARGS){
		if(l[0] == ';' || l[0] == '\n') return 0;
		if(l[0] == ' ' || l[0] == '\t') {
			l++;
			pos++;
			if(pos == 0) pos++;
		} else if(pos == 0 && l[0] != '\t'){
			// It's a label
			symtab[symcount].addr = pc;


@@ 155,12 158,12 @@ parseline(char *l)
			symtab[symcount].label = t;
			symcount++;
			pos++;
			continue;
		} else if(pos == 1){
			// It's an instruction or directive
			c = gettoken(&t, l);
			if(c == 0) return 0;
 			l += c;
			print("TOKEN: %s\n", t);
			if(strcmp(t,".END") == 0) {
				return -1;
			} else if(strcmp(t,".ORIG") == 0){


@@ 182,10 185,26 @@ parseline(char *l)
				pc++;
				pos++;
				return 1;
			} else if(strcmp(t,"RET") == 0) {
				op = OP_JMP;
				//FIXME: Add args
			} else {
				syntaxerr(smprint("Invalid instruction %s", t));
				op = matchopcode(t);
				pos++;
				if(op == -1)
					syntaxerr(smprint("Invalid instruction `%s`", t));
				l++;
			}
			inst = newinst(op);
		} else if(pos==2){
			gettoken(&t, l);
			parseargs(t, inst);
			if(debug){
				print("%d:OPCODE:%s", lineno, opcode[op]);
				for(int i = 0; i<inst->argc; i++)
					print("\tARG:%s", inst->arg[i]);
				print("\n");
			}
			return 1;
		}
	}

M tests/test.asm => tests/test.asm +5 -2
@@ 4,6 4,9 @@ MAIN	NOP
	NOP	;whatever
	NOP
JUNK	NOP
	ADD	r0,r0,x1
	BR	0x0000
	RET
	JMP	MAIN
	.END
	ADD	r0,x1
w
	ADD	r0,r0.x1