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 #define asm_rmnewline(L,S) *((L)+*(S)-1) = '\0'
49 #define asm_skipwhite(L) \
50 while((*(L)==' '||*(L)=='\t')) { \
54 void asm_init(const char *file, FILE **fp) {
55 *fp = fopen(file, "r");
59 void asm_close(FILE *fp) {
65 * Following parse states:
66 * ASM_FUNCTION -- in a function accepting input statements
75 char *name; /* name of constant */
76 int offset; /* location in globals */
78 VECTOR_MAKE(globals, assembly_constants);
82 for (; i < assembly_constants_elements; i++)
83 mem_d(assembly_constants_data[i].name);
84 mem_d(assembly_constants_data);
87 int asm_parsetype(const char *key, char **skip, long line) {
88 size_t keylen = strlen(key);
89 if (!strncmp(key, *skip, keylen)) {
90 if ((*skip)[keylen] != ':'){
91 printf("%li: Missing `:` after decltype\n", line);
95 while (**skip == ' ' || **skip == '\t')
98 if (!isalpha(**skip)) {
99 printf("%li: Invalid identififer: %s\n", line, *skip);
102 assembly_constants_add((globals) {
103 .name = util_strdup("empty"),
104 .offset = code_globals_elements
112 void asm_parse(FILE *fp) {
115 long line = 1; /* current line */
116 size_t size = 0; /* size of line */
117 asm_state state = ASM_NULL;
119 while ((data = skip = asm_getline(&size, fp)) != NULL) {
120 /* remove any whitespace at start */
121 while (*skip == ' ' || *skip == '\t')
123 /* remove newline at end of string */
124 *(skip+*(&size)-1) = '\0';
126 if (asm_parsetype(asm_keys[5], &skip, line)) {
127 if (state != ASM_NULL) {
128 printf("%li: Error unfinished function block, expected DONE or RETURN\n", line);
131 state = ASM_FUNCTION;
132 code_defs_add((prog_section_def){
134 .offset = code_globals_elements,
135 .name = code_chars_elements
137 code_globals_add(code_functions_elements);
138 code_functions_add((prog_section_function) {
139 .entry = code_statements_elements,
143 .name = code_chars_elements,
148 code_strings_add(skip);
152 /* if we make it this far then we have statements */
154 size_t i = 0; /* counter */
155 size_t o = 0; /* operands */
156 size_t c = 0; /* copy */
157 char *t = NULL; /* token */
160 * Most ops a single statement can have is three.
161 * lets allocate some space for all of those here.
163 char op[3][32768] = {{0},{0},{0}};
164 for (; i < sizeof(asm_instr)/sizeof(*asm_instr); i++) {
165 if (!strncmp(skip, asm_instr[i].m, asm_instr[i].l)) {
166 if (state != ASM_FUNCTION) {
167 printf("%li: Statement not inside function block\n", line);
171 /* update parser state */
172 if (i == INSTR_DONE || i == INSTR_RETURN) {
177 /* parse the statement */
179 o = asm_instr[i].o; /* operands */
180 skip += asm_instr[i].l; /* skip instruction */
181 t = strtok(skip, " ,");
183 while (t != NULL && i < 3) {
185 t = strtok(NULL, " ,");
191 printf("not enough operands, expected: %li, got %li\n", o, i);
194 /* TODO: hashtable value LOAD .... etc */
195 code_statements_add((prog_section_statement){
207 /* if we made it this far something is wrong */
209 printf("%li: Invalid statement, expression, or decleration\n", line);