X-Git-Url: https://git.xonotic.org/?a=blobdiff_plain;f=parse.c;h=c8ff73aee908ac6804a38b9b264d295fa0d15ebe;hb=2bfd27271444c99d02ac8de3135c6a7981b18286;hp=2d52efdec35e8b14e6c4f4854b6ef669d33e3d9e;hpb=32b804864ebfce0ed4f8ae891683d11c71ae389a;p=xonotic%2Fgmqcc.git diff --git a/parse.c b/parse.c index 2d52efd..c8ff73a 100644 --- a/parse.c +++ b/parse.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2012 + * Copyright (C) 2012 * Dale Weiler * * Permission is hereby granted, free of charge, to any person obtaining a copy of @@ -48,57 +48,57 @@ void compile_constant_debug() { * 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_gen(struct lex_file *file) { +int parse_gen(lex_file *file) { int token = 0; while ((token = lex_token(file)) != ERROR_LEX && file->length >= 0) { switch (token) { case TOKEN_TYPEDEF: { char *f; /* from */ char *t; /* to */ - - token = lex_token(file); + + token = lex_token(file); token = lex_token(file); f = util_strdup(file->lastok); - token = lex_token(file); + token = lex_token(file); token = lex_token(file); t = util_strdup(file->lastok); - + typedef_add(file, f, t); mem_d(f); mem_d(t); - + token = lex_token(file); if (token == ' ') token = lex_token(file); - + if (token != ';') error(file, ERROR_PARSE, "Expected a `;` at end of typedef statement"); - + token = lex_token(file); break; } - + case TOKEN_VOID: goto fall; case TOKEN_STRING: goto fall; case TOKEN_VECTOR: goto fall; case TOKEN_ENTITY: goto fall; case TOKEN_FLOAT: goto fall; { - fall:; + fall:; { char *name = NULL; int type = token; /* story copy */ - + /* skip over space */ token = lex_token(file); if (token == ' ') token = lex_token(file); - + /* save name */ name = util_strdup(file->lastok); - + /* skip spaces */ token = lex_token(file); if (token == ' ') token = lex_token(file); - + if (token == ';') { /* * Definitions go to the defs table, they don't have @@ -108,23 +108,27 @@ int parse_gen(struct lex_file *file) { token = lex_token(file); if (token == ' ') token = lex_token(file); - + /* strings are in file->lastok */ switch (type) { case TOKEN_VOID: error(file, ERROR_PARSE, "Cannot assign value to type void\n"); - + /* TODO: Validate (end quote), strip quotes for constant add, name constant */ case TOKEN_STRING: if (*file->lastok != '"') error(file, ERROR_PARSE, "Expected a '\"' (quote) for string constant\n"); /* add the compile-time constant */ - compile_constants_add((constant){ - .name = util_strdup(name), - .type = TYPE_STRING, - .value = {0,0,0}, - .string = util_strdup(file->lastok) - }); + { + constant c; + c.name = util_strdup(name), + c.type = TYPE_STRING, + c.value[0] = 0; + c.value[1] = 0; + c.value[2] = 0; + c.string = util_strdup(file->lastok); + compile_constants_add(c); + } break; /* TODO: name constant, old qc vec literals, whitespace fixes, name constant */ case TOKEN_VECTOR: { @@ -133,13 +137,13 @@ int parse_gen(struct lex_file *file) { float compile_calc_z = 0; int compile_calc_d = 0; /* dot? */ int compile_calc_s = 0; /* sign (-, +) */ - + char compile_data[1024]; char *compile_eval = compile_data; - + if (token != '{') - error(file, ERROR_PARSE, "Expected initializer list {} for vector constant\n"); - + error(file, ERROR_PARSE, "Expected initializer list {} for vector constant\n"); + /* * This parses a single vector element: x,y & z. This will handle all the * complicated mechanics of a vector, and can be extended as well. This @@ -188,7 +192,7 @@ int parse_gen(struct lex_file *file) { compile_calc_s = 0; \ compile_eval = &compile_data[0]; \ memset(compile_data, 0, sizeof(compile_data)) - + /* * Parse all elements using the macro above. * We must undef the macro afterwards. @@ -197,46 +201,52 @@ int parse_gen(struct lex_file *file) { PARSE_VEC_ELEMENT('y', y); PARSE_VEC_ELEMENT('z', z); #undef PARSE_VEC_ELEMENT - + /* Check for the semi-colon... */ token = lex_token(file); if (token == ' ') token = lex_token(file); if (token != ';') error(file, ERROR_PARSE, "Expected `;` on end of constant initialization for vector\n"); - + /* add the compile-time constant */ - compile_constants_add((constant){ - .name = util_strdup(name), - .type = TYPE_VECTOR, - .value = { - [0] = compile_calc_x, - [1] = compile_calc_y, - [2] = compile_calc_z - }, - .string = NULL - }); + { + constant c; + + c.name = util_strdup(name), + c.type = TYPE_VECTOR, + c.value[0] = compile_calc_x; + c.value[1] = compile_calc_y; + c.value[2] = compile_calc_z; + c.string = NULL; + compile_constants_add(c); + } break; } - + case TOKEN_ENTITY: case TOKEN_FLOAT: /*TODO: validate, constant generation, name constant */ if (!isdigit(token)) error(file, ERROR_PARSE, "Expected numeric constant for float constant\n"); - compile_constants_add((constant){ - .name = util_strdup(name), - .type = TOKEN_FLOAT, - .value = {0,0,0}, - .string = NULL - }); + /* constant */ + { + constant c; + c.name = util_strdup(name), + c.type = TOKEN_FLOAT, + c.value[0] = 0; + c.value[1] = 0; + c.value[2] = 0; + c.string = NULL; + compile_constants_add(c); + } break; } } else if (token == '(') { printf("FUNCTION ??\n"); } mem_d(name); - } - + }} + /* * From here down is all language punctuation: There is no * need to actual create tokens from these because they're already @@ -253,6 +263,8 @@ int parse_gen(struct lex_file *file) { * directives so far are #include. */ if (strncmp(file->lastok, "include", sizeof("include")) == 0) { + char *copy = NULL; + lex_file *next = NULL; /* * We only suport include " ", not <> like in C (why?) * because the latter is silly. @@ -261,20 +273,25 @@ int parse_gen(struct lex_file *file) { token = lex_token(file); if (token == '\n') return error(file, ERROR_PARSE, "Invalid use of include preprocessor directive: wanted #include \"file.h\"\n"); - - char *copy = util_strdup(file->lastok); - struct lex_file *next = lex_include(file, copy); - + + copy = util_strdup(file->lastok); + next = lex_include(file, copy); + if (!next) { error(file, ERROR_INTERNAL, "Include subsystem failure\n"); exit (-1); } - compile_constants_add((constant) { - .name = "#include", - .type = TYPE_VOID, - .value = {0,0,0}, - .string = copy - }); + /* constant */ + { + constant c; + c.name = "#include", + c.type = TYPE_VOID, + c.value[0] = 0; + c.value[1] = 0; + c.value[2] = 0; + c.string = copy; + compile_constants_add(c); + } parse_gen(next); mem_d (copy); lex_close(next); @@ -283,7 +300,7 @@ int parse_gen(struct lex_file *file) { while (token != '\n') token = lex_token(file); break; - + case LEX_IDENT: token = lex_token(file); break; @@ -293,12 +310,12 @@ int parse_gen(struct lex_file *file) { lex_reset(file); /* free constants */ { - size_t i = 0; - for (; i < compile_constants_elements; i++) { - mem_d(compile_constants_data[i].name); - mem_d(compile_constants_data[i].string); - } - mem_d(compile_constants_data); - } + size_t i = 0; + for (; i < compile_constants_elements; i++) { + mem_d(compile_constants_data[i].name); + mem_d(compile_constants_data[i].string); + } + mem_d(compile_constants_data); + } return 1; -} +}