X-Git-Url: https://git.xonotic.org/?a=blobdiff_plain;f=lexer.h;h=e58a98d13e62ba854870b19bcc0e6a46d2c90e71;hb=b5507b3127f18e10ffd15160f1bcbd84a8a1173b;hp=df42fd597104ce68b33e0ddc8021935f27c79d88;hpb=ab91dea4e0a89a56081f9747a3ee8346254a9d27;p=xonotic%2Fgmqcc.git diff --git a/lexer.h b/lexer.h index df42fd5..e58a98d 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; @@ -57,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 @@ -66,28 +69,6 @@ enum { TOKEN_FATAL /* internal error, eg out of memory */ }; -static const char *_tokennames[] = { - "TOKEN_START", - "TOKEN_IDENT", - "TOKEN_TYPENAME", - "TOKEN_OPERATOR", - "TOKEN_KEYWORD", - "TOKEN_DOTS", - "TOKEN_STRINGCONST", - "TOKEN_CHARCONST", - "TOKEN_VECTORCONST", - "TOKEN_INTCONST", - "TOKEN_FLOATCONST", - "TOKEN_EOF", - "TOKEN_ERROR", - "TOKEN_FATAL", -}; -typedef int -_all_tokennames_added_[ - ((TOKEN_FATAL - TOKEN_START + 1) == - (sizeof(_tokennames)/sizeof(_tokennames[0]))) - ? 1 : -1]; - typedef struct { char *name; int value; @@ -95,6 +76,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 */ @@ -108,16 +93,20 @@ typedef struct { struct { bool noops; + bool nodigraphs; /* used when lexing string constants */ + bool preprocessing; /* whitespace and EOLs become actual tokens */ + bool mergelines; /* backslash at the end of a line escapes the newline */ } flags; int framevalue; - MEM_VECTOR_MAKE(frame_macro, frames); + frame_macro *frames; char *modelname; -} lex_file; -MEM_VECTOR_PROTO(lex_file, char, token); + size_t push_line; +} lex_file; 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); @@ -155,6 +144,7 @@ static const oper_info c_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 }, @@ -193,6 +183,7 @@ static const oper_info c_operators[] = { { "||", 2, opid2('|','|'), ASSOC_LEFT, 4, 0 }, { "?", 3, opid2('?',':'), ASSOC_RIGHT, 3, 0 }, + { ":", 3, opid2(':','?'), ASSOC_RIGHT, 3, 0 }, { "=", 2, opid1('='), ASSOC_RIGHT, 2, 0 }, { "+=", 2, opid2('+','='), ASSOC_RIGHT, 2, 0 }, @@ -215,6 +206,7 @@ static const oper_info qcc_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 }, @@ -247,36 +239,15 @@ static const oper_info qcc_operators[] = { { "&&", 2, opid2('&','&'), ASSOC_LEFT, 5, 0 }, { "||", 2, opid2('|','|'), ASSOC_LEFT, 5, 0 }, - { ",", 2, opid1(','), ASSOC_LEFT, 1, 0 } + { ",", 2, opid1(','), ASSOC_LEFT, 2, 0 }, + + { "?", 3, opid2('?',':'), ASSOC_RIGHT, 1, 0 }, + { ":", 3, opid2(':','?'), ASSOC_RIGHT, 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; - -typedef struct -{ - lex_file *lex; - int error; - lex_ctx ctx; - - token *tokens; - token *lastok; - - token *tok; /* current token */ - - MEM_VECTOR_MAKE(ast_value*, globals); -} parse_file; - -MEM_VECTOR_PROTO(parse_file, ast_value*, globals); - -parse_file* parse_open(const char *file); -void parse_file_close(parse_file*); - -bool parse(parse_file*); - -bool parse_iskey(parse_file *self, const char *ident); - void lexerror(lex_file*, const char *fmt, ...); #endif