X-Git-Url: https://git.xonotic.org/?p=xonotic%2Fgmqcc.git;a=blobdiff_plain;f=lexer.h;h=76d2b7a711c9ce8f5a2e8ddf704778328c92bb70;hp=a2f06acf7cb189ebff47fcdbb10bea2698583d31;hb=091173341eace2d290f6c0ebc4159c3afca7fbaa;hpb=deb7ccb8302f4477cf085740b9dfc7e0d11da47f diff --git a/lexer.h b/lexer.h index a2f06ac..76d2b7a 100644 --- a/lexer.h +++ b/lexer.h @@ -8,7 +8,7 @@ typedef struct token_s token; struct token_s { int ttype; - MEM_VECTOR_MAKE(char, value); + char *value; union { vector v; @@ -17,17 +17,21 @@ struct token_s { int t; /* type */ } constval; +#if 0 struct token_s *next; struct token_s *prev; +#endif lex_ctx ctx; }; +#if 0 token* token_new(); void token_delete(token*); token* token_copy(const token *cp); void token_delete_all(token *t); token* token_copy_all(const token *cp); +#endif /* Lexer * @@ -53,6 +57,9 @@ enum { TOKEN_INTCONST, TOKEN_FLOATCONST, + TOKEN_WHITE, + TOKEN_EOL, + TOKEN_EOF, /* We use '< TOKEN_ERROR', so TOKEN_FATAL must come after it and any @@ -74,6 +81,8 @@ static const char *_tokennames[] = { "TOKEN_VECTORCONST", "TOKEN_INTCONST", "TOKEN_FLOATCONST", + "TOKEN_WHITE", + "TOKEN_EOL", "TOKEN_EOF", "TOKEN_ERROR", "TOKEN_FATAL", @@ -91,6 +100,10 @@ typedef struct { typedef struct { FILE *file; + const char *open_string; + size_t open_string_length; + size_t open_string_pos; + char *name; size_t line; size_t sline; /* line at the start of a token */ @@ -100,20 +113,21 @@ typedef struct { bool eof; - token *tok; + token tok; /* not a pointer anymore */ struct { bool noops; + bool nodigraphs; /* used when lexing string constants */ + bool preprocessing; /* whitespace and EOLs become actual tokens */ } flags; int framevalue; - MEM_VECTOR_MAKE(frame_macro, frames); + frame_macro *frames; char *modelname; } lex_file; -MEM_VECTOR_PROTO(lex_file, char, token); - lex_file* lex_open (const char *file); +lex_file* lex_open_string(const char *str, size_t len, const char *name); void lex_close(lex_file *lex); int lex_do (lex_file *lex); void lex_cleanup(void); @@ -143,7 +157,7 @@ typedef struct { #define opid2(a,b) ((a<<8)|b) #define opid3(a,b,c) ((a<<16)|(b<<8)|c) -static const oper_info operators[] = { +static const oper_info c_operators[] = { { "(", 0, opid1('('), ASSOC_LEFT, 99, OP_PREFIX}, /* paren expression - non function call */ { "++", 1, opid3('S','+','+'), ASSOC_LEFT, 16, OP_SUFFIX}, @@ -151,6 +165,7 @@ static const oper_info operators[] = { { ".", 2, opid1('.'), ASSOC_LEFT, 15, 0 }, { "(", 0, opid1('('), ASSOC_LEFT, 15, 0 }, /* function call */ + { "[", 2, opid1('['), ASSOC_LEFT, 15, 0 }, /* array subscript */ { "!", 1, opid2('!', 'P'), ASSOC_RIGHT, 14, OP_PREFIX }, { "~", 1, opid2('~', 'P'), ASSOC_RIGHT, 14, OP_PREFIX }, @@ -204,31 +219,52 @@ static const oper_info operators[] = { { ",", 2, opid1(','), ASSOC_LEFT, 1, 0 } }; -static const size_t operator_count = (sizeof(operators) / sizeof(operators[0])); +static const size_t c_operator_count = (sizeof(c_operators) / sizeof(c_operators[0])); -typedef struct -{ - lex_file *lex; - int error; - lex_ctx ctx; +static const oper_info qcc_operators[] = { + { "(", 0, opid1('('), ASSOC_LEFT, 99, OP_PREFIX}, /* paren expression - non function call */ - token *tokens; - token *lastok; + { ".", 2, opid1('.'), ASSOC_LEFT, 15, 0 }, + { "(", 0, opid1('('), ASSOC_LEFT, 15, 0 }, /* function call */ + { "[", 2, opid1('['), ASSOC_LEFT, 15, 0 }, /* array subscript */ - token *tok; /* current token */ + { "!", 1, opid2('!', 'P'), ASSOC_RIGHT, 14, OP_PREFIX }, + { "+", 1, opid2('+','P'), ASSOC_RIGHT, 14, OP_PREFIX }, + { "-", 1, opid2('-','P'), ASSOC_RIGHT, 14, OP_PREFIX }, - MEM_VECTOR_MAKE(ast_value*, globals); -} parse_file; + { "*", 2, opid1('*'), ASSOC_LEFT, 13, 0 }, + { "/", 2, opid1('/'), ASSOC_LEFT, 13, 0 }, + { "&", 2, opid1('&'), ASSOC_LEFT, 13, 0 }, + { "|", 2, opid1('|'), ASSOC_LEFT, 13, 0 }, -MEM_VECTOR_PROTO(parse_file, ast_value*, globals); + { "+", 2, opid1('+'), ASSOC_LEFT, 12, 0 }, + { "-", 2, opid1('-'), ASSOC_LEFT, 12, 0 }, -parse_file* parse_open(const char *file); -void parse_file_close(parse_file*); + { "<", 2, opid1('<'), ASSOC_LEFT, 10, 0 }, + { ">", 2, opid1('>'), ASSOC_LEFT, 10, 0 }, + { "<=", 2, opid2('<','='), ASSOC_LEFT, 10, 0 }, + { ">=", 2, opid2('>','='), ASSOC_LEFT, 10, 0 }, + { "==", 2, opid2('=','='), ASSOC_LEFT, 10, 0 }, + { "!=", 2, opid2('!','='), ASSOC_LEFT, 10, 0 }, + + { "=", 2, opid1('='), ASSOC_RIGHT, 8, 0 }, + { "+=", 2, opid2('+','='), ASSOC_RIGHT, 8, 0 }, + { "-=", 2, opid2('-','='), ASSOC_RIGHT, 8, 0 }, + { "*=", 2, opid2('*','='), ASSOC_RIGHT, 8, 0 }, + { "/=", 2, opid2('/','='), ASSOC_RIGHT, 8, 0 }, + { "%=", 2, opid2('%','='), ASSOC_RIGHT, 8, 0 }, + { "&=", 2, opid2('&','='), ASSOC_RIGHT, 8, 0 }, + { "|=", 2, opid2('|','='), ASSOC_RIGHT, 8, 0 }, -bool parse(parse_file*); + { "&&", 2, opid2('&','&'), ASSOC_LEFT, 5, 0 }, + { "||", 2, opid2('|','|'), ASSOC_LEFT, 5, 0 }, -bool parse_iskey(parse_file *self, const char *ident); + { ",", 2, opid1(','), ASSOC_LEFT, 1, 0 } +}; +static const size_t qcc_operator_count = (sizeof(qcc_operators) / sizeof(qcc_operators[0])); +extern const oper_info *operators; +extern size_t operator_count; void lexerror(lex_file*, const char *fmt, ...); #endif