@@ 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;
}
}
@@ 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