5 * Permission is hereby granted, free of charge, to any person obtaining a copy of
6 * this software and associated documentation files (the "Software"), to deal in
7 * the Software without restriction, including without limitation the rights to
8 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
9 * of the Software, and to permit persons to whom the Software is furnished to do
10 * so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included in all
13 * copies or substantial portions of the Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25 * Some assembler keywords not part of the opcodes above: these are
26 * for creating functions, or constants.
28 const char *const asm_keys[] = {
29 "FLOAT" , /* define float */
30 "VECTOR" , /* define vector */
31 "ENTITY" , /* define ent */
32 "FIELD" , /* define field */
33 "STRING" , /* define string */
37 static char *const asm_getline(size_t *byte, FILE *fp) {
39 ssize_t read = util_getline(&line, byte, fp);
48 void asm_init(const char *file, FILE **fp) {
49 *fp = fopen(file, "r");
53 void asm_close(FILE *fp) {
59 * Following parse states:
60 * ASM_FUNCTION -- in a function accepting input statements
69 char *name; /* name of constant */
70 int offset; /* location in globals */
72 VECTOR_MAKE(globals, assembly_constants);
76 for (; i < assembly_constants_elements; i++)
77 mem_d(assembly_constants_data[i].name);
78 mem_d(assembly_constants_data);
81 int asm_parsetype(const char *key, char **skip, long line) {
82 size_t keylen = strlen(key);
83 if (!strncmp(key, *skip, keylen)) {
84 if ((*skip)[keylen] != ':'){
85 printf("%li: Missing `:` after decltype\n", line);
89 while (**skip == ' ' || **skip == '\t')
92 if (!isalpha(**skip)) {
93 printf("%li: Invalid identififer: %s\n", line, *skip);
96 assembly_constants_add((globals) {
97 .name = util_strdup("empty"),
98 .offset = code_globals_elements
106 void asm_parse(FILE *fp) {
109 long line = 1; /* current line */
110 size_t size = 0; /* size of line */
111 asm_state state = ASM_NULL;
113 while ((data = skip = asm_getline(&size, fp)) != NULL) {
114 /* remove any whitespace at start */
115 while (*skip == ' ' || *skip == '\t')
117 /* remove newline at end of string */
118 *(skip+*(&size)-1) = '\0';
120 if (asm_parsetype(asm_keys[5], &skip, line)) {
121 if (state != ASM_NULL) {
122 printf("%li: Error unfinished function block, expected DONE or RETURN\n", line);
125 state = ASM_FUNCTION;
126 code_defs_add((prog_section_def){
128 .offset = code_globals_elements,
129 .name = code_chars_elements
131 code_globals_add(code_functions_elements);
132 code_functions_add((prog_section_function) {
133 .entry = code_statements_elements,
137 .name = code_chars_elements,
142 code_strings_add(skip);
146 /* if we make it this far then we have statements */
148 size_t i = 0; /* counter */
149 size_t o = 0; /* operands */
150 size_t c = 0; /* copy */
151 char *t = NULL; /* token */
154 * Most ops a single statement can have is three.
155 * lets allocate some space for all of those here.
157 char op[3][32768] = {{0},{0},{0}};
158 for (; i < sizeof(asm_instr)/sizeof(*asm_instr); i++) {
159 if (!strncmp(skip, asm_instr[i].m, asm_instr[i].l)) {
160 if (state != ASM_FUNCTION) {
161 printf("%li: Statement not inside function block\n", line);
165 /* update parser state */
166 if (i == INSTR_DONE || i == INSTR_RETURN) {
171 /* parse the statement */
173 o = asm_instr[i].o; /* operands */
174 skip += asm_instr[i].l; /* skip instruction */
175 t = strtok(skip, " ,");
177 while (t != NULL && i < 3) {
179 t = strtok(NULL, " ,");
185 printf("not enough operands, expected: %li, got %li\n", o, i);
188 /* TODO: hashtable value LOAD .... etc */
189 code_statements_add((prog_section_statement){
201 /* if we made it this far something is wrong */
203 printf("%li: Invalid statement, expression, or decleration\n", line);