VECTOR_MAKE(prog_section_function, code_functions );
VECTOR_MAKE(int, code_globals );
VECTOR_MAKE(char, code_strings );
+static uint16_t code_crc16 = 0;
+prog_header code_header ={0};
-/* program header */
-prog_header code_header;
-void code_write() {
-
- #if 0
- /* Add test program */
- code_strings_add('\0');
-
- const char *X;
- size_t size = sizeof(X);
- size_t iter = 0;
+void code_init() {
+ /*
+ * The way progs.dat is suppose to work is odd, there needs to be
+ * some null (empty) statements, functions, and 28 globals
+ */
+ prog_section_function empty_function = {0,0,0,0,0,0,0,{0}};
+ prog_section_statement empty_statement = {0,{0},{0},{0}};
+ int i;
+ for(i = 0; i < 28; i++)
+ code_globals_add(0);
+
+ code_strings_add ('\0');
+ code_functions_add (empty_function);
+ code_statements_add(empty_statement);
+}
+
+void code_test() {
+ const char *X;
+ size_t size = sizeof(X);
+ size_t iter = 0;
#define FOO(Y) \
X = Y; \
FOO("m_toggle");
FOO("m_shutdown");
- int i;
- for (i=0; i<28; i++)
- code_globals_add(0); /* 28 empty */
-
code_globals_add(1); /* m_init */
code_globals_add(2); /* print */
code_globals_add(14); /* hello world in string table */
code_defs_add((prog_section_def){.type=TYPE_FUNCTION,.offset=29/*globals[29]*/, .name=8 }); /* print */
code_defs_add((prog_section_def){.type=TYPE_STRING, .offset=30/*globals[30]*/, .name=14}); /*hello_world*/
- code_functions_add((prog_section_function){0, 0, 0, 0, .name=0, 0, 0, {0}}); /* NULL */
code_functions_add((prog_section_function){1, 0, 0, 0, .name=1, 0, 0, {0}}); /* m_init */
code_functions_add((prog_section_function){-4, 0, 0, 0, .name=8, 0, 0, {0}}); /* print */
code_functions_add((prog_section_function){0, 0, 0, 0, .name=14+13, 0,0, {0}}); /* m_keydown */
code_functions_add((prog_section_function){0, 0, 0, 0, .name=14+13+10+7, 0,0, {0}});
code_functions_add((prog_section_function){0, 0, 0, 0, .name=14+13+10+7+9, 0,0, {0}});
- code_statements_add((prog_section_statement){0, 0, 0, 0}); /* NULL */
- code_statements_add((prog_section_statement){INSTR_STORE_F, 30/*30 is hello_world */, OFS_PARM0, 0});
- code_statements_add((prog_section_statement){INSTR_CALL1, 29/*29 is print */, 0, 0});
- code_statements_add((prog_section_statement){INSTR_RETURN, 0, 0, 0});
+ code_statements_add((prog_section_statement){INSTR_STORE_F, {30}/*30 is hello_world */, {OFS_PARM0}, {0}});
+ code_statements_add((prog_section_statement){INSTR_CALL1, {29}/*29 is print */, {0}, {0}});
+ code_statements_add((prog_section_statement){INSTR_RETURN, {0}, {0}, {0}});
code_header.version = 6;
code_header.crc16 = 0; /* TODO: */
code_header.globals = (prog_section){code_header.functions.offset + sizeof(prog_section_function) *code_functions_elements, code_globals_elements };
code_header.strings = (prog_section){code_header.globals.offset + sizeof(int) *code_globals_elements, code_strings_elements };
code_header.entfield = 0; /* TODO: */
- #endif
-
+}
- /* write out everything one SHOT! */
+/* program header */
+void code_write() {
+ code_init();
+ code_test();
+
FILE *fp = fopen("program.dat", "wb");
fwrite(&code_header, 1, sizeof(prog_header), fp);
fwrite(code_statements_data, 1, sizeof(prog_section_statement)*code_statements_elements, fp);
"." , "<" , ">" , "&" , "|" ,
#endif
-#define STORE(X) { \
- printf(X); \
- break; \
+#define STORE(X,C) { \
+ long f = fill; \
+ while(f--) { \
+ putchar(' '); \
+ } \
+ fill C; \
+ printf(X); \
+ break; \
}
void parse_debug(struct parsenode *tree) {
+ long fill = 0;
while (tree) {
switch (tree->type) {
- case PARSE_TYPE_ADD: STORE("OPERATOR: ADD \n");
- case PARSE_TYPE_BAND: STORE("OPERATOR: BITAND \n");
- case PARSE_TYPE_BOR: STORE("OPERATOR: BITOR \n");
- case PARSE_TYPE_COMMA: STORE("OPERATOR: SEPERATOR\n");
- case PARSE_TYPE_DOT: STORE("OPERATOR: DOT\n");
- case PARSE_TYPE_DIVIDE: STORE("OPERATOR: DIVIDE\n");
- case PARSE_TYPE_EQUAL: STORE("OPERATOR: ASSIGNMENT\n");
+ case PARSE_TYPE_ADD: STORE("OPERATOR: ADD \n", -=0);
+ case PARSE_TYPE_BAND: STORE("OPERATOR: BITAND \n",-=0);
+ case PARSE_TYPE_BOR: STORE("OPERATOR: BITOR \n",-=0);
+ case PARSE_TYPE_COMMA: STORE("OPERATOR: SEPERATOR\n",-=0);
+ case PARSE_TYPE_DOT: STORE("OPERATOR: DOT\n",-=0);
+ case PARSE_TYPE_DIVIDE: STORE("OPERATOR: DIVIDE\n",-=0);
+ case PARSE_TYPE_EQUAL: STORE("OPERATOR: ASSIGNMENT\n",-=0);
- case PARSE_TYPE_BREAK: STORE("STATEMENT: BREAK \n");
- case PARSE_TYPE_CONTINUE: STORE("STATEMENT: CONTINUE\n");
- case PARSE_TYPE_GOTO: STORE("STATEMENT: GOTO\n");
- case PARSE_TYPE_RETURN: STORE("STATEMENT: RETURN\n");
- case PARSE_TYPE_DONE: STORE("STATEMENT: DONE\n");
+ case PARSE_TYPE_BREAK: STORE("STATEMENT: BREAK \n",-=0);
+ case PARSE_TYPE_CONTINUE: STORE("STATEMENT: CONTINUE\n",-=0);
+ case PARSE_TYPE_GOTO: STORE("STATEMENT: GOTO\n",-=0);
+ case PARSE_TYPE_RETURN: STORE("STATEMENT: RETURN\n",-=0);
+ case PARSE_TYPE_DONE: STORE("STATEMENT: DONE\n",-=0);
- case PARSE_TYPE_VOID: STORE("DECLTYPE: VOID\n");
- case PARSE_TYPE_STRING: STORE("DECLTYPE: STRING\n");
- case PARSE_TYPE_ELIP: STORE("DECLTYPE: VALIST\n");
- case PARSE_TYPE_ENTITY: STORE("DECLTYPE: ENTITY\n");
- case PARSE_TYPE_FLOAT: STORE("DECLTYPE: FLOAT\n");
- case PARSE_TYPE_VECTOR: STORE("DECLTYPE: VECTOR\n");
+ case PARSE_TYPE_VOID: STORE("DECLTYPE: VOID\n",-=0);
+ case PARSE_TYPE_STRING: STORE("DECLTYPE: STRING\n",-=0);
+ case PARSE_TYPE_ELIP: STORE("DECLTYPE: VALIST\n",-=0);
+ case PARSE_TYPE_ENTITY: STORE("DECLTYPE: ENTITY\n",-=0);
+ case PARSE_TYPE_FLOAT: STORE("DECLTYPE: FLOAT\n",-=0);
+ case PARSE_TYPE_VECTOR: STORE("DECLTYPE: VECTOR\n",-=0);
- case PARSE_TYPE_GT: STORE("TEST: GREATER THAN\n");
- case PARSE_TYPE_LT: STORE("TEST: LESS THAN\n");
- case PARSE_TYPE_GTEQ: STORE("TEST: GREATER THAN OR EQUAL\n");
- case PARSE_TYPE_LTEQ: STORE("TEST: LESS THAN OR EQUAL\n");
- case PARSE_TYPE_LNEQ: STORE("TEST: NOT EQUAL\n");
- case PARSE_TYPE_EQEQ: STORE("TEST: EQUAL-EQUAL\n");
+ case PARSE_TYPE_GT: STORE("TEST: GREATER THAN\n",-=0);
+ case PARSE_TYPE_LT: STORE("TEST: LESS THAN\n",-=0);
+ case PARSE_TYPE_GTEQ: STORE("TEST: GREATER THAN OR EQUAL\n",-=0);
+ case PARSE_TYPE_LTEQ: STORE("TEST: LESS THAN OR EQUAL\n",-=0);
+ case PARSE_TYPE_LNEQ: STORE("TEST: NOT EQUAL\n",-=0);
+ case PARSE_TYPE_EQEQ: STORE("TEST: EQUAL-EQUAL\n",-=0);
- case PARSE_TYPE_LBS: STORE("BLOCK: BEG\n");
- case PARSE_TYPE_RBS: STORE("BLOCK: END\n");
- case PARSE_TYPE_ELSE: STORE("BLOCK: ELSE\n");
- case PARSE_TYPE_IF: STORE("BLOCK: IF\n");
+ case PARSE_TYPE_LBS: STORE("BLOCK: BEG\n",+=4);
+ case PARSE_TYPE_RBS: STORE("BLOCK: END\n",-=4);
+ case PARSE_TYPE_ELSE: STORE("BLOCK: ELSE\n",+=0);
+ case PARSE_TYPE_IF: STORE("BLOCK: IF\n",+=0);
- case PARSE_TYPE_LAND: STORE("LOGICAL: AND\n");
- case PARSE_TYPE_LNOT: STORE("LOGICAL: NOT\n");
- case PARSE_TYPE_LOR: STORE("LOGICAL: OR\n");
+ case PARSE_TYPE_LAND: STORE("LOGICAL: AND\n",-=0);
+ case PARSE_TYPE_LNOT: STORE("LOGICAL: NOT\n",-=0);
+ case PARSE_TYPE_LOR: STORE("LOGICAL: OR\n",-=0);
- case PARSE_TYPE_LPARTH: STORE("PARTH: BEG\n");
- case PARSE_TYPE_RPARTH: STORE("PARTH: END\n");
+ case PARSE_TYPE_LPARTH: STORE("PARTH: BEG\n",-=0);
+ case PARSE_TYPE_RPARTH: STORE("PARTH: END\n",-=0);
- case PARSE_TYPE_WHILE: STORE("LOOP: WHILE\n");
- case PARSE_TYPE_FOR: STORE("LOOP: FOR\n");
- case PARSE_TYPE_DO: STORE("LOOP: DO\n");
-
- //case PARSE_TYPE_IDENT: STORE("IDENT: ???\n");
+ case PARSE_TYPE_WHILE: STORE("LOOP: WHILE\n",-=0);
+ case PARSE_TYPE_FOR: STORE("LOOP: FOR\n",-=0);
+ case PARSE_TYPE_DO: STORE("LOOP: DO\n",-=0);
}
tree = tree->next;
}
typedef_clear();
}
+const char *STRING_(char ch) {
+ if (ch == ' ')
+ return "<space>";
+ if (ch == '\n')
+ return "<newline>";
+ if (ch == '\0')
+ return "<null>";
+
+ return &ch;
+}
+
+#define TOKEN_SKIPWHITE() \
+ token = lex_token(file); \
+ while (token == ' ') { \
+ token = lex_token(file); \
+ }
+
/*
* Generates a parse tree out of the lexees generated by the lexer. This
* is where the tree is built. This is where valid check is performed.
token != ERROR_PREPRO && file->length >= 0) {
switch (token) {
case TOKEN_IF:
- token = lex_token(file);
+ TOKEN_SKIPWHITE();
if (token != '(')
- error(ERROR_PARSE, "Expected `(` on if statement:\n");
+ error(ERROR_PARSE, "%s:%d Expected `(` after `if` for if statement\n", file->name, file->line);
PARSE_TREE_ADD(PARSE_TYPE_IF);
PARSE_TREE_ADD(PARSE_TYPE_LPARTH);
break;
PARSE_TREE_ADD(PARSE_TYPE_ELSE);
break;
case TOKEN_FOR:
- //token = lex_token(file);
while ((token == ' ' || token == '\n') && file->length >= 0)
token = lex_token(file);
PARSE_TREE_ADD(PARSE_TYPE_FOR);
case TOKEN_BREAK: PARSE_PERFORM(PARSE_TYPE_BREAK, {});
case TOKEN_GOTO: PARSE_PERFORM(PARSE_TYPE_GOTO, {});
case TOKEN_VOID: PARSE_PERFORM(PARSE_TYPE_VOID, {});
- case TOKEN_STRING: PARSE_PERFORM(PARSE_TYPE_STRING, {});
- case TOKEN_FLOAT: PARSE_PERFORM(PARSE_TYPE_FLOAT, {});
- case TOKEN_VECTOR: PARSE_PERFORM(PARSE_TYPE_VECTOR, {});
- case TOKEN_ENTITY: PARSE_PERFORM(PARSE_TYPE_ENTITY, {});
+
+ case TOKEN_STRING: PARSE_TREE_ADD(PARSE_TYPE_STRING);
+ case TOKEN_VECTOR: PARSE_TREE_ADD(PARSE_TYPE_VECTOR);
+ case TOKEN_ENTITY: PARSE_TREE_ADD(PARSE_TYPE_ENTITY);
+ case TOKEN_FLOAT: PARSE_TREE_ADD(PARSE_TYPE_FLOAT);
+ /* fall into this for all types */
+ {
+ char *name = NULL;
+ TOKEN_SKIPWHITE();
+ name = util_strdup(file->lastok);
+ //token = lex_token (file);
+
+ /* is it NOT a definition? */
+ if (token != ';') {
+ while (token == ' ')
+ token = lex_token(file);
+
+ /* it's a function? */
+ if (token == '(') {
+ /*
+ * Now I essentially have to do a ton of parsing for
+ * function definition.
+ */
+ PARSE_TREE_ADD(PARSE_TYPE_LPARTH);
+ token = lex_token(file);
+ while (token != '\n' && token != ')') {
+ switch (token) {
+ case TOKEN_VOID: PARSE_TREE_ADD(PARSE_TYPE_VOID); break;
+ case TOKEN_STRING: PARSE_TREE_ADD(PARSE_TYPE_STRING); break;
+ case TOKEN_ENTITY: PARSE_TREE_ADD(PARSE_TYPE_ENTITY); break;
+ case TOKEN_FLOAT: PARSE_TREE_ADD(PARSE_TYPE_FLOAT); break;
+ /*
+ * TODO: Need to parse function pointers: I have no clue how
+ * I'm actually going to pull that off, it's going to be hard
+ * since you can have a function pointer-pointer-pointer ....
+ */
+ }
+ }
+ /* just a definition */
+ if (token == ')') {
+ /*
+ * I like to put my { on the same line as the ) for
+ * functions, ifs, elses, so we must support that!.
+ */
+ PARSE_TREE_ADD(PARSE_TYPE_RPARTH);
+ token = lex_token(file);
+ token = lex_token(file);
+ if(token == '{')
+ PARSE_TREE_ADD(PARSE_TYPE_LBS);
+ }
+ else if (token == '\n')
+ error(ERROR_COMPILER, "%s:%d Expecting `;` after function definition %s\n", file->name, file->line, name);
+
+ } else if (token == '=') {
+ PARSE_TREE_ADD(PARSE_TYPE_EQUAL);
+ } else {
+ error(ERROR_COMPILER, "%s:%d Invalid decltype: expected `(` [function], or `=` [constant] for %s\n", file->name, file->line, name);
+ }
+ } else {
+ /* definition */
+ printf("FOUND DEFINITION\n");
+ }
+ mem_d(name);
+ }
/*
* From here down is all language punctuation: There is no
*/
case '#':
token = lex_token(file); /* skip '#' */
- while (isspace(token)) {
- if (token == '\n')
- return error(ERROR_PARSE, "Expected valid preprocessor directive after `#` %s\n");
- token = lex_token(file); /* try again */
- }
+ //while (isspace(token)) {
+ // if (token == '\n')
+ // return error(ERROR_PARSE, "Expected valid preprocessor directive after `#` %s\n");
+ // token = lex_token(file); /* try again */
+ //}
/*
* If we make it here we found a directive, the supported
* directives so far are #include.