typedef.o \
util.o \
code.o \
- assembler.c
+ asm.c
%.o: %.c
$(CC) -c $< -o $@ $(CFLAGS)
--- /dev/null
+/*
+ * Copyright (C) 2012
+ * Dale Weiler
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+ * of the Software, and to permit persons to whom the Software is furnished to do
+ * so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#include "gmqcc.h"
+/*
+ * Some assembler keywords not part of the opcodes above: these are
+ * for creating functions, or constants.
+ */
+const char *const asm_keys[] = {
+ "FLOAT" , /* define float */
+ "VECTOR" , /* define vector */
+ "ENTITY" , /* define ent */
+ "FIELD" , /* define field */
+ "STRING" , /* define string */
+ "FUNCTION"
+};
+
+static char *const asm_getline(size_t *byte, FILE *fp) {
+ char *line = NULL;
+ ssize_t read = util_getline(&line, byte, fp);
+ *byte = read;
+ if (read == -1) {
+ mem_d (line);
+ return NULL;
+ }
+ return line;
+}
+
+void asm_init(const char *file, FILE **fp) {
+ *fp = fopen(file, "r");
+ code_init();
+}
+
+void asm_close(FILE *fp) {
+ 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_clear() {
+ size_t i = 0;
+ for (; i < assembly_constants_elements; i++)
+ mem_d(assembly_constants_data[i].name);
+ 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;
+ 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) {
+ 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 = skip = asm_getline(&size, fp)) != NULL) {
+ /* remove any whitespace at start */
+ while (*skip == ' ' || *skip == '\t')
+ 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_strings_add(skip);
+ };
+
+ #if 0
+ /* if we make it this far then we have statements */
+ {
+ size_t i = 0; /* counter */
+ 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);
+ line ++;
+ }
+ asm_clear();
+}
+++ /dev/null
-/*
- * Copyright (C) 2012
- * Dale Weiler
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
- * of the Software, and to permit persons to whom the Software is furnished to do
- * so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- */
-#include "gmqcc.h"
-/*
- * Some assembler keywords not part of the opcodes above: these are
- * for creating functions, or constants.
- */
-const char *const asm_keys[] = {
- "FLOAT" , /* define float */
- "VECTOR" , /* define vector */
- "ENTITY" , /* define ent */
- "FIELD" , /* define field */
- "STRING" , /* define string */
- "FUNCTION"
-};
-
-static char *const asm_getline(size_t *byte, FILE *fp) {
- char *line = NULL;
- ssize_t read = util_getline(&line, byte, fp);
- *byte = read;
- if (read == -1) {
- mem_d (line);
- return NULL;
- }
- return line;
-}
-
-void asm_init(const char *file, FILE **fp) {
- *fp = fopen(file, "r");
- code_init();
-}
-
-void asm_close(FILE *fp) {
- 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_clear() {
- size_t i = 0;
- for (; i < assembly_constants_elements; i++)
- mem_d(assembly_constants_data[i].name);
- 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;
- 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) {
- 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 = skip = asm_getline(&size, fp)) != NULL) {
- /* remove any whitespace at start */
- while (*skip == ' ' || *skip == '\t')
- 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_strings_add(skip);
- };
-
- #if 0
- /* if we make it this far then we have statements */
- {
- size_t i = 0; /* counter */
- 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);
- line ++;
- }
- asm_clear();
-}