X-Git-Url: https://git.xonotic.org/?a=blobdiff_plain;f=parse.c;h=0e1c6a511d84473c70187ebbd7cc0fa2f5e4f012;hb=bd5ba9e0fe0e9bdaea3f869f55d8f40651a2d0fb;hp=4e820c70d84c7219f80f1033df708018d824fb3c;hpb=506f4bca1bdb14fcf745128b7e6681ba62b89fd7;p=xonotic%2Fgmqcc.git diff --git a/parse.c b/parse.c index 4e820c7..0e1c6a5 100644 --- a/parse.c +++ b/parse.c @@ -92,19 +92,13 @@ "." , "<" , ">" , "&" , "|" , #endif -#define STORE(X) { \ - printf(X); \ - break; \ +#define STORE(X) { \ + printf(X); \ + break; \ } void parse_debug(struct parsenode *tree) { - while (tree && tree->next != NULL) { - /* skip blanks */ - if (tree->type == 0) { - tree = tree->next; - continue; - } - + while (tree) { switch (tree->type) { case PARSE_TYPE_ADD: STORE("OPERATOR: ADD \n"); case PARSE_TYPE_BAND: STORE("OPERATOR: BITAND \n"); @@ -150,22 +144,27 @@ void parse_debug(struct parsenode *tree) { 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_IDENT: STORE("IDENT: ???\n"); } tree = tree->next; } } /* - * This just skips the token and throws it in the parse tree for later - * checking / optimization / codegen, it doesn't do anything with it - * like syntax check for legal use -- like it should as it's a TODO item - * which is not implemented + * Performs a parse operation: This is a macro to prevent bugs, if the + * calls to lex_token are'nt exactly enough to feed to the end of the + * actual lexees for the current thing that is being parsed, the state + * of the next iteration in the creation of the parse tree will be wrong + * and everything will fail. */ -#define PARSE_TODO(X) { \ - token = lex_token(file); \ - PARSE_TREE_ADD(X); \ - break; \ +#define PARSE_PERFORM(X,C) { \ + token = lex_token(file); \ + { C } \ + while (token != '\n') { \ + token = lex_token(file); \ + } \ + PARSE_TREE_ADD(X); \ + break; \ } void parse_clear(struct parsenode *tree) { @@ -176,9 +175,16 @@ void parse_clear(struct parsenode *tree) { tree = tree->next; mem_d (temp); } + + /* free any potential typedefs */ + typedef_clear(); } -int parse(struct lex_file *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. + */ +int parse_tree(struct lex_file *file) { struct parsenode *parsetree = NULL; struct parsenode *parseroot = NULL; @@ -191,7 +197,8 @@ int parse(struct lex_file *file) { parseroot = mem_a(sizeof(struct parsenode)); if (!parseroot) return error(ERROR_INTERNAL, "Ran out of memory", " "); - parsetree = parseroot; + parsetree = parseroot; + parsetree->type = -1; /* not a valid type -- root element */ } int token = 0; @@ -202,27 +209,18 @@ int parse(struct lex_file *file) { token != ERROR_PREPRO && file->length >= 0) { switch (token) { case TOKEN_IF: - token = lex_token(file); - //while ((token == ' ' || token == '\n') && file->length >= 0) - // token = lex_token(file); - - //if (token != '(') - // error(ERROR_PARSE, "Expected `(` after if\n", ""); - + while ((token == ' ' || token == '\n') && file->length >= 0) + token = lex_token(file); PARSE_TREE_ADD(PARSE_TYPE_IF); break; case TOKEN_ELSE: token = lex_token(file); - //while ((token == ' ' || token == '\n') && file->length >= 0) - // token = lex_token(file); - 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); - + //token = lex_token(file); + while ((token == ' ' || token == '\n') && file->length >= 0) + token = lex_token(file); PARSE_TREE_ADD(PARSE_TYPE_FOR); break; @@ -241,24 +239,34 @@ int parse(struct lex_file *file) { typedef_add(f, t); - /* free stdup strings */ - mem_d(f); - mem_d(t); + free(f); + free(t); + + while (token != '\n') + token = lex_token(file); break; } + + /* + * Returns are addable as-is, statement checking is during + * the actual parse tree check. + */ + case TOKEN_RETURN: + PARSE_TREE_ADD(PARSE_TYPE_RETURN); + break; + //PARSE_PERFORM(PARSE_TYPE_RETURN, {}); + - - case TOKEN_DO: PARSE_TODO(PARSE_TYPE_DO); - case TOKEN_WHILE: PARSE_TODO(PARSE_TYPE_WHILE); - case TOKEN_BREAK: PARSE_TODO(PARSE_TYPE_BREAK); - case TOKEN_CONTINUE: PARSE_TODO(PARSE_TYPE_CONTINUE); - case TOKEN_RETURN: PARSE_TODO(PARSE_TYPE_RETURN); - case TOKEN_GOTO: PARSE_TODO(PARSE_TYPE_GOTO); - case TOKEN_VOID: PARSE_TODO(PARSE_TYPE_VOID); - case TOKEN_STRING: PARSE_TODO(PARSE_TYPE_STRING); - case TOKEN_FLOAT: PARSE_TODO(PARSE_TYPE_FLOAT); - case TOKEN_VECTOR: PARSE_TODO(PARSE_TYPE_VECTOR); - case TOKEN_ENTITY: PARSE_TODO(PARSE_TYPE_ENTITY); + case TOKEN_DO: PARSE_PERFORM(PARSE_TYPE_DO, {}); + case TOKEN_WHILE: PARSE_PERFORM(PARSE_TYPE_WHILE, {}); + case TOKEN_BREAK: PARSE_PERFORM(PARSE_TYPE_BREAK, {}); + case TOKEN_CONTINUE: PARSE_PERFORM(PARSE_TYPE_CONTINUE,{}); + 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, {}); /* * From here down is all language punctuation: There is no @@ -281,6 +289,11 @@ int parse(struct lex_file *file) { token = lex_token(file); break; + case '.': + token = lex_token(file); + PARSE_TREE_ADD(PARSE_TYPE_DOT); + break; + case '(': token = lex_token(file); PARSE_TREE_ADD(PARSE_TYPE_LPARTH); @@ -380,6 +393,5 @@ int parse(struct lex_file *file) { parse_debug(parseroot); lex_reset(file); parse_clear(parseroot); - return 1; }