/*
- * Copyright (C) 2012
+ * Copyright (C) 2012
* Dale Weiler
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
* 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(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
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: {
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
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.
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
* 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.
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);
- 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);
while (token != '\n')
token = lex_token(file);
break;
-
+
case LEX_IDENT:
token = lex_token(file);
break;
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;
-}
+}