Working on the assembler

This commit is contained in:
Dale Weiler 2012-04-27 16:31:38 -04:00
parent 8e13e8ab11
commit 7aee8ac2ef
3 changed files with 23 additions and 119 deletions

126
asm.c
View file

@ -78,132 +78,20 @@ void asm_clear() {
mem_d(assembly_constants_data); mem_d(assembly_constants_data);
} }
int asm_parsetype(const char *key, char **skip, long line) {
size_t keylen = strlen(key);
if (!strncmp(key, *skip, keylen)) {
if ((*skip)[keylen] != ':'){
printf("%li: Missing `:` after decltype\n", line);
exit(1);
}
*skip += keylen+1;
/* skip whitespace */
while (**skip == ' ' || **skip == '\t')
(*skip)++;
if (!isalpha(**skip)) {
printf("%li: Invalid identififer: %s\n", line, *skip);
exit(1);
} else {
assembly_constants_add((globals) {
.name = util_strdup("empty"),
.offset = code_globals_elements
});
return 1;
}
}
return 0;
}
void asm_parse(FILE *fp) { void asm_parse(FILE *fp) {
char *data = NULL; char *data = NULL;
char *skip = NULL;
long line = 1; /* current line */ long line = 1; /* current line */
size_t size = 0; /* size of line */ size_t size = 0; /* size of line */
asm_state state = ASM_NULL; asm_state state = ASM_NULL;
while ((data = skip = asm_getline(&size, fp)) != NULL) { while ((data = asm_getline(&size, fp)) != NULL) {
/* remove any whitespace at start */ data = util_strsws(data); /* skip whitespace */
while (*skip == ' ' || *skip == '\t') data = util_strrnl(data); /* delete newline */
skip++;
/* remove newline at end of string */
*(skip+*(&size)-1) = '\0';
if (asm_parsetype(asm_keys[5], &skip, line)) {
if (state != ASM_NULL) {
printf("%li: Error unfinished function block, expected DONE or RETURN\n", line);
goto end;
}
state = ASM_FUNCTION;
code_defs_add((prog_section_def){
.type = TYPE_VOID,
.offset = code_globals_elements,
.name = code_chars_elements
});
code_globals_add(code_functions_elements);
code_functions_add((prog_section_function) {
.entry = code_statements_elements,
.firstlocal = 0,
.locals = 0,
.profile = 0,
.name = code_chars_elements,
.file = 0,
.nargs = 0,
.argsize = {0}
});
code_chars_put(skip, strlen(skip));
};
#if 0 /* TODO: everything */
/* if we make it this far then we have statements */ (void)state;
{ goto end;
size_t i = 0; /* counter */ end:
size_t o = 0; /* operands */
size_t c = 0; /* copy */
char *t = NULL; /* token */
/*
* Most ops a single statement can have is three.
* lets allocate some space for all of those here.
*/
char op[3][32768] = {{0},{0},{0}};
for (; i < sizeof(asm_instr)/sizeof(*asm_instr); i++) {
if (!strncmp(skip, asm_instr[i].m, asm_instr[i].l)) {
if (state != ASM_FUNCTION) {
printf("%li: Statement not inside function block\n", line);
goto end;
}
/* update parser state */
if (i == INSTR_DONE || i == INSTR_RETURN) {
goto end;
state = ASM_NULL;
}
/* parse the statement */
c = i;
o = asm_instr[i].o; /* operands */
skip += asm_instr[i].l; /* skip instruction */
t = strtok(skip, " ,");
i = 0;
while (t != NULL && i < 3) {
strcpy(op[i], t);
t = strtok(NULL, " ,");
i ++;
}
/* check */
if (i != o) {
printf("not enough operands, expected: %li, got %li\n", o, i);
}
/* TODO: hashtable value LOAD .... etc */
code_statements_add((prog_section_statement){
c,
{ atof(op[0]) },
{ atof(op[1]) },
{ atof(op[2]) }
});
goto end;
}
}
}
#endif
/* if we made it this far something is wrong */
if (*skip != '\0')
printf("%li: Invalid statement %s, expression, or decleration\n", line, skip);
end:
mem_d(data); mem_d(data);
line ++; line ++;
} }

View file

@ -197,6 +197,7 @@ void util_meminfo ();
char *util_strdup (const char *); char *util_strdup (const char *);
char *util_strrq (char *); char *util_strrq (char *);
char *util_strrnl (char *); char *util_strrnl (char *);
char *util_strsws (char *);
void util_debug (const char *, const char *, ...); void util_debug (const char *, const char *, ...);
int util_getline (char **, size_t *, FILE *); int util_getline (char **, size_t *, FILE *);
void util_endianswap (void *, int, int); void util_endianswap (void *, int, int);

15
util.c
View file

@ -132,6 +132,21 @@ char *util_strrnl(char *src) {
return src; return src;
} }
/*
* Removes any whitespace prefixed on a string by moving
* skipping past it, and stroing the skip distance, so
* the string can later be freed (if it was allocated)
*/
char *util_strsws(char *skip) {
size_t size = 0;
if (!skip)
return NULL;
while (*skip == ' ' || *skip == '\t')
skip++,size++;
return skip-size;
}
void util_debug(const char *area, const char *ms, ...) { void util_debug(const char *area, const char *ms, ...) {
if (!opts_debug) if (!opts_debug)
return; return;