const size_t o; /* operands */
const size_t l; /* menomic len */
} const asm_instr[] = {
- [INSTR_DONE] = { "DONE" , 0, 4 },
- [INSTR_MUL_F] = { "MUL_F" , 0, 5 },
- [INSTR_MUL_V] = { "MUL_V" , 0, 5 },
- [INSTR_MUL_FV] = { "MUL_FV" , 0, 6 },
- [INSTR_MUL_VF] = { "MUL_VF" , 0, 6 },
+ [INSTR_DONE] = { "DONE" , 1, 4 },
+ [INSTR_MUL_F] = { "MUL_F" , 3, 5 },
+ [INSTR_MUL_V] = { "MUL_V" , 3, 5 },
+ [INSTR_MUL_FV] = { "MUL_FV" , 3, 6 },
+ [INSTR_MUL_VF] = { "MUL_VF" , 3, 6 },
[INSTR_DIV_F] = { "DIV" , 0, 3 },
- [INSTR_ADD_F] = { "ADD_F" , 0, 5 },
- [INSTR_ADD_V] = { "ADD_V" , 0, 5 },
- [INSTR_SUB_F] = { "SUB_F" , 0, 5 },
- [INSTR_SUB_V] = { "DUB_V" , 0, 5 },
+ [INSTR_ADD_F] = { "ADD_F" , 3, 5 },
+ [INSTR_ADD_V] = { "ADD_V" , 3, 5 },
+ [INSTR_SUB_F] = { "SUB_F" , 3, 5 },
+ [INSTR_SUB_V] = { "DUB_V" , 3, 5 },
[INSTR_EQ_F] = { "EQ_F" , 0, 4 },
[INSTR_EQ_V] = { "EQ_V" , 0, 4 },
[INSTR_EQ_S] = { "EQ_S" , 0, 4 },
static char *const asm_getline(size_t *byte, FILE *fp) {
char *line = NULL;
- ssize_t read = getline(&line, byte, fp);
+ ssize_t read = util_getline(&line, byte, fp);
*byte = read;
if (read == -1) {
- free (line);
+ mem_d (line);
return NULL;
}
return line;
fclose(fp);
code_write();
}
+
+/*
+ * Following parse states:
+ * ASM_FUNCTION -- in a function accepting input statements
+ * ....
+ */
+typedef enum {
+ ASM_NULL,
+ ASM_FUNCTION
+} asm_state;
+
+typedef struct {
+ char *name; /* name of constant */
+ int offset; /* location in globals */
+} globals;
+VECTOR_MAKE(globals, assembly_constants);
void asm_parse(FILE *fp) {
- char *data = NULL;
- char *skip = NULL;
- long line = 1; /* current line */
- size_t size = 0; /* size of line */
+ char *data = NULL;
+ char *skip = NULL;
+ long line = 1; /* current line */
+ size_t size = 0; /* size of line */
+ asm_state state = ASM_NULL;
while ((data = asm_getline(&size, fp)) != NULL) {
skip = data;
(void)offset_functions; \
(void)offset_fields; \
(void)offset_defs; \
+ assembly_constants_add((globals){ \
+ .name = util_strdup(skip), \
+ .offset = offset_globals \
+ }); \
} \
goto end; \
}
.offset = offset_globals, /* offset to offset in string table (for data)*/
.name = offset_chars /* location of name in string table (for name)*/
});
+ code_strings_add('h');
});
/* FUNCTION */
DECLTYPE(asm_keys[5], {
/* TODO: parse */
+ 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 = offset_globals,
/* if we make it this far then we have statements */
{
- size_t i = 0;
+ size_t i = 0; /* counter */
+ size_t o = 0; /* operands */
+ 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)) {
- /* TODO */
+ 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 */
+ 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 ++;
+ }
+
+ util_debug("ASM", "Operand 1: %s\n", util_strrnl(op[0]));
+ util_debug("ASM", "Operand 2: %s\n", util_strrnl(op[1]));
+ util_debug("ASM", "Operand 3: %s\n", util_strrnl(op[2]));
+
+ /* 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){
+ i, {0}, {0}, {0}
+ });
goto end;
}
}
}
/* if we made it this far something is wrong */
- printf("ERROR");
+ if (*skip != '\0')
+ printf("%li: Invalid statement, expression, or decleration\n", line);
end:
- free(data);
+ //free(data);
+ mem_d(data);
+ line ++;
}
}