X-Git-Url: https://git.xonotic.org/?a=blobdiff_plain;f=lexer.h;h=c84b2084ee57c0e854696b886b79f0132ce42d42;hb=5e4b8846d1838c6c0244646b2a3f81c94a647b13;hp=f49b8ff2fe349a6407c5955affba02e86922303f;hpb=09fa41318de29930b9c0f909d76d66a7317414fe;p=xonotic%2Fgmqcc.git diff --git a/lexer.h b/lexer.h index f49b8ff..c84b208 100644 --- a/lexer.h +++ b/lexer.h @@ -45,6 +45,8 @@ enum { TOKEN_KEYWORD, /* loop */ + TOKEN_DOTS, /* 3 dots, ... */ + TOKEN_STRINGCONST, /* not the typename but an actual "string" */ TOKEN_CHARCONST, TOKEN_VECTORCONST, @@ -66,6 +68,7 @@ static const char *_tokennames[] = { "TOKEN_TYPENAME", "TOKEN_OPERATOR", "TOKEN_KEYWORD", + "TOKEN_DOTS", "TOKEN_STRINGCONST", "TOKEN_CHARCONST", "TOKEN_VECTORCONST", @@ -81,6 +84,11 @@ _all_tokennames_added_[ (sizeof(_tokennames)/sizeof(_tokennames[0]))) ? 1 : -1]; +typedef struct { + char *name; + int value; +} frame_macro; + typedef struct { FILE *file; char *name; @@ -90,11 +98,17 @@ typedef struct { char peek[256]; size_t peekpos; + bool eof; + token *tok; struct { bool noops; } flags; + + int framevalue; + MEM_VECTOR_MAKE(frame_macro, frames); + char *modelname; } lex_file; MEM_VECTOR_PROTO(lex_file, char, token); @@ -102,6 +116,7 @@ MEM_VECTOR_PROTO(lex_file, char, token); lex_file* lex_open (const char *file); void lex_close(lex_file *lex); int lex_do (lex_file *lex); +void lex_cleanup(void); /* Parser * @@ -117,67 +132,123 @@ enum { typedef struct { const char *op; + unsigned int operands; + unsigned int id; unsigned int assoc; unsigned int prec; unsigned int flags; } oper_info; -static const oper_info operators[] = { - { "++", ASSOC_LEFT, 16, OP_SUFFIX}, - { "--", ASSOC_LEFT, 16, OP_SUFFIX}, +#define opid1(a) (a) +#define opid2(a,b) ((a<<8)|b) +#define opid3(a,b,c) ((a<<16)|(b<<8)|c) - { ".", ASSOC_LEFT, 15, 0 }, +static const oper_info c_operators[] = { + { "(", 0, opid1('('), ASSOC_LEFT, 99, OP_PREFIX}, /* paren expression - non function call */ - { "!", ASSOC_RIGHT, 14, 0 }, - { "~", ASSOC_RIGHT, 14, 0 }, - { "+", ASSOC_RIGHT, 14, OP_PREFIX }, - { "-", ASSOC_RIGHT, 14, OP_PREFIX }, - { "++", ASSOC_RIGHT, 14, OP_PREFIX }, - { "--", ASSOC_RIGHT, 14, OP_PREFIX }, -/* { "&", ASSOC_RIGHT, 14, OP_PREFIX }, */ + { "++", 1, opid3('S','+','+'), ASSOC_LEFT, 16, OP_SUFFIX}, + { "--", 1, opid3('S','-','-'), ASSOC_LEFT, 16, OP_SUFFIX}, - { "*", ASSOC_LEFT, 13, 0 }, - { "/", ASSOC_LEFT, 13, 0 }, - { "%", ASSOC_LEFT, 13, 0 }, + { ".", 2, opid1('.'), ASSOC_LEFT, 15, 0 }, + { "(", 0, opid1('('), ASSOC_LEFT, 15, 0 }, /* function call */ - { "+", ASSOC_LEFT, 12, 0 }, - { "-", ASSOC_LEFT, 12, 0 }, + { "!", 1, opid2('!', 'P'), ASSOC_RIGHT, 14, OP_PREFIX }, + { "~", 1, opid2('~', 'P'), ASSOC_RIGHT, 14, OP_PREFIX }, + { "+", 1, opid2('+','P'), ASSOC_RIGHT, 14, OP_PREFIX }, + { "-", 1, opid2('-','P'), ASSOC_RIGHT, 14, OP_PREFIX }, + { "++", 1, opid3('+','+','P'), ASSOC_RIGHT, 14, OP_PREFIX }, + { "--", 1, opid3('-','-','P'), ASSOC_RIGHT, 14, OP_PREFIX }, +/* { "&", 1, opid2('&','P'), ASSOC_RIGHT, 14, OP_PREFIX }, */ - { "<<", ASSOC_LEFT, 11, 0 }, - { ">>", ASSOC_LEFT, 11, 0 }, + { "*", 2, opid1('*'), ASSOC_LEFT, 13, 0 }, + { "/", 2, opid1('/'), ASSOC_LEFT, 13, 0 }, + { "%", 2, opid1('%'), ASSOC_LEFT, 13, 0 }, - { "<", ASSOC_LEFT, 10, 0 }, - { ">", ASSOC_LEFT, 10, 0 }, - { "<=", ASSOC_LEFT, 10, 0 }, - { ">=", ASSOC_LEFT, 10, 0 }, + { "+", 2, opid1('+'), ASSOC_LEFT, 12, 0 }, + { "-", 2, opid1('-'), ASSOC_LEFT, 12, 0 }, - { "==", ASSOC_LEFT, 9, 0 }, - { "!=", ASSOC_LEFT, 9, 0 }, + { "<<", 2, opid2('<','<'), ASSOC_LEFT, 11, 0 }, + { ">>", 2, opid2('>','>'), ASSOC_LEFT, 11, 0 }, - { "&", ASSOC_LEFT, 8, 0 }, + { "<", 2, opid1('<'), ASSOC_LEFT, 10, 0 }, + { ">", 2, opid1('>'), ASSOC_LEFT, 10, 0 }, + { "<=", 2, opid2('<','='), ASSOC_LEFT, 10, 0 }, + { ">=", 2, opid2('>','='), ASSOC_LEFT, 10, 0 }, - { "^", ASSOC_LEFT, 7, 0 }, + { "==", 2, opid2('=','='), ASSOC_LEFT, 9, 0 }, + { "!=", 2, opid2('!','='), ASSOC_LEFT, 9, 0 }, - { "|", ASSOC_LEFT, 6, 0 }, + { "&", 2, opid1('&'), ASSOC_LEFT, 8, 0 }, - { "&&", ASSOC_LEFT, 5, 0 }, + { "^", 2, opid1('^'), ASSOC_LEFT, 7, 0 }, - { "||", ASSOC_LEFT, 4, 0 }, + { "|", 2, opid1('|'), ASSOC_LEFT, 6, 0 }, - { "?", ASSOC_RIGHT, 3, 0 }, + { "&&", 2, opid2('&','&'), ASSOC_LEFT, 5, 0 }, - { "=", ASSOC_RIGHT, 2, 0 }, - { "+=", ASSOC_RIGHT, 2, 0 }, - { "-=", ASSOC_RIGHT, 2, 0 }, - { "*=", ASSOC_RIGHT, 2, 0 }, - { "/=", ASSOC_RIGHT, 2, 0 }, - { "%=", ASSOC_RIGHT, 2, 0 }, - { ">>=", ASSOC_RIGHT, 2, 0 }, - { "<<=", ASSOC_RIGHT, 2, 0 }, - { "&=", ASSOC_RIGHT, 2, 0 }, - { "^=", ASSOC_RIGHT, 2, 0 }, - { "|=", ASSOC_RIGHT, 2, 0 }, + { "||", 2, opid2('|','|'), ASSOC_LEFT, 4, 0 }, + + { "?", 3, opid2('?',':'), ASSOC_RIGHT, 3, 0 }, + + { "=", 2, opid1('='), ASSOC_RIGHT, 2, 0 }, + { "+=", 2, opid2('+','='), ASSOC_RIGHT, 2, 0 }, + { "-=", 2, opid2('-','='), ASSOC_RIGHT, 2, 0 }, + { "*=", 2, opid2('*','='), ASSOC_RIGHT, 2, 0 }, + { "/=", 2, opid2('/','='), ASSOC_RIGHT, 2, 0 }, + { "%=", 2, opid2('%','='), ASSOC_RIGHT, 2, 0 }, + { ">>=", 2, opid3('>','>','='), ASSOC_RIGHT, 2, 0 }, + { "<<=", 2, opid3('<','<','='), ASSOC_RIGHT, 2, 0 }, + { "&=", 2, opid2('&','='), ASSOC_RIGHT, 2, 0 }, + { "^=", 2, opid2('^','='), ASSOC_RIGHT, 2, 0 }, + { "|=", 2, opid2('|','='), ASSOC_RIGHT, 2, 0 }, + + { ",", 2, opid1(','), ASSOC_LEFT, 1, 0 } }; +static const size_t c_operator_count = (sizeof(c_operators) / sizeof(c_operators[0])); + +static const oper_info qcc_operators[] = { + { "(", 0, opid1('('), ASSOC_LEFT, 99, OP_PREFIX}, /* paren expression - non function call */ + + { ".", 2, opid1('.'), ASSOC_LEFT, 15, 0 }, + { "(", 0, opid1('('), ASSOC_LEFT, 15, 0 }, /* function call */ + + { "!", 1, opid2('!', 'P'), ASSOC_RIGHT, 14, OP_PREFIX }, + { "+", 1, opid2('+','P'), ASSOC_RIGHT, 14, OP_PREFIX }, + { "-", 1, opid2('-','P'), ASSOC_RIGHT, 14, OP_PREFIX }, + + { "*", 2, opid1('*'), ASSOC_LEFT, 13, 0 }, + { "/", 2, opid1('/'), ASSOC_LEFT, 13, 0 }, + { "&", 2, opid1('&'), ASSOC_LEFT, 13, 0 }, + { "|", 2, opid1('|'), ASSOC_LEFT, 13, 0 }, + + { "+", 2, opid1('+'), ASSOC_LEFT, 12, 0 }, + { "-", 2, opid1('-'), ASSOC_LEFT, 12, 0 }, + + { "<", 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 }, + + { "&&", 2, opid2('&','&'), ASSOC_LEFT, 5, 0 }, + { "||", 2, opid2('|','|'), ASSOC_LEFT, 5, 0 }, + + { ",", 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; typedef struct {