cb22561995-10-11Fredrik Hübinette (Hubbe) /*\
06983f1996-09-22Fredrik Hübinette (Hubbe) ||| This file a part of Pike, and is copyright by Fredrik Hubinette ||| Pike is distributed as GPL (General Public License)
cb22561995-10-11Fredrik Hübinette (Hubbe) ||| See the files COPYING and DISCLAIMER for more information. \*/
5267b71995-08-09Fredrik Hübinette (Hubbe) #include "global.h"
61e9a01998-01-25Fredrik Hübinette (Hubbe) RCSID("$Id: lex.c,v 1.40 1998/01/25 08:25:09 hubbe Exp $");
5267b71995-08-09Fredrik Hübinette (Hubbe) #include "language.h" #include "array.h" #include "lex.h" #include "stralloc.h" #include "dynamic_buffer.h"
06983f1996-09-22Fredrik Hübinette (Hubbe) #include "constants.h"
5267b71995-08-09Fredrik Hübinette (Hubbe) #include "hashtable.h" #include "stuff.h"
9aa6fa1997-05-19Fredrik Hübinette (Hubbe) #include "pike_memory.h"
5267b71995-08-09Fredrik Hübinette (Hubbe) #include "interpret.h" #include "error.h" #include "object.h" #include "las.h" #include "operators.h" #include "opcodes.h"
06983f1996-09-22Fredrik Hübinette (Hubbe) #include "builtin_functions.h" #include "main.h"
9c6f7d1997-04-15Fredrik Hübinette (Hubbe) #include "mapping.h"
5267b71995-08-09Fredrik Hübinette (Hubbe) 
bb55f81997-03-16Fredrik Hübinette (Hubbe) #include "pike_macros.h"
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) 
bdfb861997-12-22Fredrik Hübinette (Hubbe) #ifdef HAVE_SYS_PARAM_H
5267b71995-08-09Fredrik Hübinette (Hubbe) #include <sys/param.h>
bdfb861997-12-22Fredrik Hübinette (Hubbe) #endif
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) 
5267b71995-08-09Fredrik Hübinette (Hubbe) #include <ctype.h> #include <math.h> #include <fcntl.h> #include <errno.h>
78ec7a1996-06-21Fredrik Hübinette (Hubbe) #include "time_stuff.h"
5267b71995-08-09Fredrik Hübinette (Hubbe)  #define LEXDEBUG 0
be478c1997-08-30Henrik Grubbström (Grubba) void exit_lex(void)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
06983f1996-09-22Fredrik Hübinette (Hubbe) #ifdef DEBUG
e82b301997-01-29Fredrik Hübinette (Hubbe)  if(p_flag)
06983f1996-09-22Fredrik Hübinette (Hubbe)  { int e; fprintf(stderr,"Opcode usage: (opcode, runned, compiled)\n"); for(e=0;e<F_MAX_OPCODE-F_OFFSET;e++) { fprintf(stderr,":: %-20s %8ld %8ld\n", low_get_f_name(e+F_OFFSET,0), (long)instrs[e].runs, (long)instrs[e].compiles); } } #endif
5267b71995-08-09Fredrik Hübinette (Hubbe) } struct keyword instr_names[]= { { "!", F_NOT }, { "!=", F_NE }, { "%", F_MOD }, { "%=", F_MOD_EQ },
2d12341997-03-10Fredrik Hübinette (Hubbe) { "& global", F_GLOBAL_LVALUE, I_HASARG }, { "& local", F_LOCAL_LVALUE, I_HASARG },
5267b71995-08-09Fredrik Hübinette (Hubbe) { "&", F_AND }, { "&=", F_AND_EQ }, { "*", F_MULTIPLY }, { "*=", F_MULT_EQ }, { "+", F_ADD }, { "++x", F_INC }, { "+=", F_ADD_EQ }, { "-", F_SUBTRACT }, { "--x", F_DEC }, { "-=", F_SUB_EQ }, { "/", F_DIVIDE }, { "/=", F_DIV_EQ }, { "<", F_LT }, { "<<", F_LSH }, { "<<=", F_LSH_EQ }, { "<=", F_LE }, { "==", F_EQ }, { ">", F_GT }, { ">=", F_GE }, { ">>", F_RSH }, { ">>=", F_RSH_EQ }, { "@", F_PUSH_ARRAY }, { "^", F_XOR }, { "^=", F_XOR_EQ }, { "arg+=1024", F_PREFIX_1024 }, { "arg+=256", F_PREFIX_256 }, { "arg+=256*X", F_PREFIX_CHARX256 }, { "arg+=256*XX", F_PREFIX_WORDX256 }, { "arg+=256*XXX", F_PREFIX_24BITX256 }, { "arg+=512", F_PREFIX_512 }, { "arg+=768", F_PREFIX_768 }, { "assign and pop", F_ASSIGN_AND_POP },
2d12341997-03-10Fredrik Hübinette (Hubbe) { "assign global", F_ASSIGN_GLOBAL, I_HASARG }, { "assign global and pop", F_ASSIGN_GLOBAL_AND_POP, I_HASARG }, { "assign local", F_ASSIGN_LOCAL, I_HASARG }, { "assign local and pop", F_ASSIGN_LOCAL_AND_POP, I_HASARG },
5267b71995-08-09Fredrik Hübinette (Hubbe) { "assign", F_ASSIGN }, { "break", F_BREAK }, { "case", F_CASE }, { "cast", F_CAST }, { "const-1", F_CONST_1 },
2d12341997-03-10Fredrik Hübinette (Hubbe) { "constant", F_CONSTANT, I_HASARG },
5267b71995-08-09Fredrik Hübinette (Hubbe) { "continue", F_CONTINUE }, { "copy_value", F_COPY_VALUE }, { "default", F_DEFAULT }, { "do-while", F_DO }, { "dumb return", F_DUMB_RETURN }, { "float number", F_FLOAT }, { "for", F_FOR },
2d12341997-03-10Fredrik Hübinette (Hubbe) { "global", F_GLOBAL, I_HASARG },
5267b71995-08-09Fredrik Hübinette (Hubbe) { "index", F_INDEX },
2d12341997-03-10Fredrik Hübinette (Hubbe) { "->", F_ARROW, I_HASARG },
2e15561997-01-17Fredrik Hübinette (Hubbe) { "clear string subtype", F_CLEAR_STRING_SUBTYPE },
2d12341997-03-10Fredrik Hübinette (Hubbe) { "arrow string", F_ARROW_STRING, I_HASARG },
5267b71995-08-09Fredrik Hübinette (Hubbe) { "indirect", F_INDIRECT },
2d12341997-03-10Fredrik Hübinette (Hubbe)  { "branch", F_BRANCH, I_ISJUMP }, { "branch non zero", F_BRANCH_WHEN_NON_ZERO, I_ISJUMP }, { "branch when zero", F_BRANCH_WHEN_ZERO, I_ISJUMP }, { "branch if <", F_BRANCH_WHEN_LT, I_ISJUMP }, { "branch if >", F_BRANCH_WHEN_GT, I_ISJUMP }, { "branch if <=", F_BRANCH_WHEN_LE, I_ISJUMP }, { "branch if >=", F_BRANCH_WHEN_GE, I_ISJUMP }, { "branch if ==", F_BRANCH_WHEN_EQ, I_ISJUMP }, { "branch if !=", F_BRANCH_WHEN_NE, I_ISJUMP }, { "++Loop", F_INC_LOOP, I_ISJUMP }, { "++Loop!=", F_INC_NEQ_LOOP, I_ISJUMP }, { "--Loop", F_DEC_LOOP, I_ISJUMP }, { "--Loop!=", F_DEC_NEQ_LOOP, I_ISJUMP }, { "&&", F_LAND, I_ISJUMP }, { "||", F_LOR, I_ISJUMP }, { "==||", F_EQ_OR, I_ISJUMP }, { "==&&", F_EQ_AND, I_ISJUMP }, { "catch", F_CATCH, I_ISJUMP }, { "foreach", F_FOREACH, I_ISJUMP }, { "data", F_POINTER, I_ISPOINTER }, { "local function call",F_CALL_LFUN, I_HASARG }, { "local function call and pop",F_CALL_LFUN_AND_POP, I_HASARG }, { "local function", F_LFUN, I_HASARG }, { "local", F_LOCAL, I_HASARG },
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) { "external", F_EXTERNAL, I_HASARG }, { "& external", F_EXTERNAL_LVALUE, I_HASARG }, { "LDA", F_LDA, I_HASARG },
2d12341997-03-10Fredrik Hübinette (Hubbe) { "mark & local", F_MARK_AND_LOCAL, I_HASARG },
5267b71995-08-09Fredrik Hübinette (Hubbe) { "ltosval2", F_LTOSVAL2 }, { "lvalue to svalue", F_LTOSVAL }, { "lvalue_list", F_LVALUE_LIST }, { "mark", F_MARK },
06abc01996-08-03Fredrik Hübinette (Hubbe) { "mark mark", F_MARK2 },
2d12341997-03-10Fredrik Hübinette (Hubbe) { "negative number", F_NEG_NUMBER, I_HASARG }, { "number", F_NUMBER, I_HASARG },
5267b71995-08-09Fredrik Hübinette (Hubbe) { "pop", F_POP_VALUE },
2d12341997-03-10Fredrik Hübinette (Hubbe) { "pop_n_elems", F_POP_N_ELEMS, I_HASARG },
5267b71995-08-09Fredrik Hübinette (Hubbe) { "push 0", F_CONST0 }, { "push 1", F_CONST1 },
da48821996-04-13Fredrik Hübinette (Hubbe) { "push 0x7fffffff", F_BIGNUM },
5267b71995-08-09Fredrik Hübinette (Hubbe) { "range", F_RANGE }, { "return", F_RETURN }, { "return 0", F_RETURN_0 },
3c04e81997-03-13Fredrik Hübinette (Hubbe) { "return 1", F_RETURN_1 },
2d12341997-03-10Fredrik Hübinette (Hubbe) { "sscanf", F_SSCANF, I_HASARG }, { "string", F_STRING, I_HASARG }, { "switch", F_SWITCH, I_HASARG },
5267b71995-08-09Fredrik Hübinette (Hubbe) { "unary minus", F_NEGATE }, { "while", F_WHILE }, { "x++ and pop", F_INC_AND_POP }, { "x++", F_POST_INC }, { "x-- and pop", F_DEC_AND_POP }, { "x--", F_POST_DEC }, { "|", F_OR }, { "|=", F_OR_EQ }, { "~", F_COMPL },
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) { "label", F_LABEL,1 },
2d12341997-03-10Fredrik Hübinette (Hubbe) { "align", F_ALIGN, I_HASARG }, { "call", F_APPLY, I_HASARG }, { "clear local", F_CLEAR_LOCAL, I_HASARG }, { "clear 2 local", F_CLEAR_2_LOCAL, I_HASARG }, { "++local", F_INC_LOCAL, I_HASARG }, { "++local and pop", F_INC_LOCAL_AND_POP, I_HASARG }, { "local++", F_POST_INC_LOCAL, I_HASARG }, { "--local", F_DEC_LOCAL, I_HASARG }, { "--local and pop", F_DEC_LOCAL_AND_POP, I_HASARG }, { "local--", F_POST_DEC_LOCAL, I_HASARG },
06abc01996-08-03Fredrik Hübinette (Hubbe) { "sizeof", F_SIZEOF },
2d12341997-03-10Fredrik Hübinette (Hubbe) { "sizeof local", F_SIZEOF_LOCAL, I_HASARG },
06abc01996-08-03Fredrik Hübinette (Hubbe) { "throw(0)", F_THROW_ZERO },
2d12341997-03-10Fredrik Hübinette (Hubbe) { "string index", F_STRING_INDEX, I_HASARG }, { "local index", F_LOCAL_INDEX, I_HASARG }, { "int index", F_POS_INT_INDEX, I_HASARG }, { "-int index", F_NEG_INT_INDEX, I_HASARG }, { "apply and pop", F_APPLY_AND_POP, I_HASARG }, { "2 locals", F_2_LOCALS, I_HASARG }, { "byte", F_BYTE, I_HASARG },
419fab1997-03-09Fredrik Hübinette (Hubbe) { "nop", F_NOP },
3c04e81997-03-13Fredrik Hübinette (Hubbe) { "add integer", F_ADD_INT, I_HASARG }, { "add -integer", F_ADD_NEG_INT, I_HASARG }, { "mark & call", F_MARK_APPLY, I_HASARG }, { "mark, call & pop", F_MARK_APPLY_POP, I_HASARG },
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) { "apply and return", F_APPLY_AND_RETURN, I_HASARG }, { "call lfun & return", F_CALL_LFUN_AND_RETURN, I_HASARG }, { "call function", F_CALL_FUNCTION, 0 }, { "call function & return", F_CALL_FUNCTION_AND_RETURN, 0 },
5267b71995-08-09Fredrik Hübinette (Hubbe) }; struct instr instrs[F_MAX_INSTR - F_OFFSET]; struct reserved { struct hash_entry link; int token; };
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) void init_lex()
5267b71995-08-09Fredrik Hübinette (Hubbe) { unsigned int i; for(i=0; i<NELEM(instr_names);i++) { if(instr_names[i].token >= F_MAX_INSTR) fatal("Error in instr_names[%u]\n\n",i);
e82b301997-01-29Fredrik Hübinette (Hubbe)  if(instrs[instr_names[i].token - F_OFFSET].name) fatal("Duplicate name for %s\n",instr_names[i].word);
5267b71995-08-09Fredrik Hübinette (Hubbe)  instrs[instr_names[i].token - F_OFFSET].name = instr_names[i].word;
2d12341997-03-10Fredrik Hübinette (Hubbe)  instrs[instr_names[i].token - F_OFFSET].flags=instr_names[i].flags;
5267b71995-08-09Fredrik Hübinette (Hubbe)  } } char *low_get_f_name(int n,struct program *p) { static char buf[30]; if (n<F_MAX_OPCODE && instrs[n-F_OFFSET].name) { return instrs[n-F_OFFSET].name; }else if(n >= F_MAX_OPCODE) { if(p &&
5c8e891995-10-29Fredrik Hübinette (Hubbe)  (int)p->num_constants > (int)(n-F_MAX_OPCODE) &&
5267b71995-08-09Fredrik Hübinette (Hubbe)  p->constants[n-F_MAX_OPCODE].type==T_FUNCTION &&
bdb5091996-09-25Fredrik Hübinette (Hubbe)  (p->constants[n-F_MAX_OPCODE].subtype == FUNCTION_BUILTIN) &&
5267b71995-08-09Fredrik Hübinette (Hubbe)  p->constants[n-F_MAX_OPCODE].u.efun) { return p->constants[n-F_MAX_OPCODE].u.efun->name->str; }else{ sprintf(buf, "Call efun %d", n - F_MAX_OPCODE); return buf; } }else{ sprintf(buf, "<OTHER %d>", n); return buf; } } char *get_f_name(int n) { static char buf[30]; if (n<F_MAX_OPCODE && instrs[n-F_OFFSET].name) { return instrs[n-F_OFFSET].name; }else if(n >= F_MAX_OPCODE) { if(fp && fp->context.prog &&
5c8e891995-10-29Fredrik Hübinette (Hubbe)  (int)fp->context.prog->num_constants > (int)(n-F_MAX_OPCODE) &&
5267b71995-08-09Fredrik Hübinette (Hubbe)  fp->context.prog->constants[n-F_MAX_OPCODE].type==T_FUNCTION &&
bdb5091996-09-25Fredrik Hübinette (Hubbe)  fp->context.prog->constants[n-F_MAX_OPCODE].subtype == FUNCTION_BUILTIN &&
5267b71995-08-09Fredrik Hübinette (Hubbe)  fp->context.prog->constants[n-F_MAX_OPCODE].u.efun) { return fp->context.prog->constants[n-F_MAX_OPCODE].u.efun->name->str; }else{ sprintf(buf, "Call efun %d", n - F_MAX_OPCODE); return buf; } }else{ sprintf(buf, "<OTHER %d>", n); return buf; } }
0d202a1995-10-20Fredrik Hübinette (Hubbe) char *get_token_name(int n) { static char buf[30]; if (n<F_MAX_INSTR && instrs[n-F_OFFSET].name) { return instrs[n-F_OFFSET].name; }else{ sprintf(buf, "<OTHER %d>", n); return buf; } }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) struct lex lex;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
2916001998-01-16Henrik Grubbström (Grubba) #define LOOK() (*((unsigned char *)lex.pos))
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) #define GETC() (*(lex.pos++)) #define GOBBLE(c) (LOOK()==c?(lex.pos++,1):0) #define SKIPSPACE() do { while(ISSPACE(LOOK()) && LOOK()!='\n') lex.pos++; }while(0) #define SKIPWHITE() do { while(ISSPACE(LOOK())) lex.pos++; }while(0) #define SKIPUPTO(X) do { while(LOOK()!=(X) && LOOK()) lex.pos++; }while(0)
5267b71995-08-09Fredrik Hübinette (Hubbe) 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) #define READBUF(X) { \ register int C; \ buf=lex.pos; \ while((C=LOOK()) && (X)) lex.pos++; \ len=lex.pos - buf; \
5267b71995-08-09Fredrik Hübinette (Hubbe) }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) #define TWO_CHAR(X,Y) ((X)<<8)+(Y) #define ISWORD(X) (len==(long)strlen(X) && !MEMCMP(buf,X,strlen(X)))
5267b71995-08-09Fredrik Hübinette (Hubbe) 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) /*** Lexical analyzing ***/
5267b71995-08-09Fredrik Hübinette (Hubbe) 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) static int char_const(void)
5267b71995-08-09Fredrik Hübinette (Hubbe) { int c;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  switch(c=GETC())
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  case 0: lex.pos--; yyerror("Unexpected end of file\n"); return 0; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': c-='0'; if(LOOK()<'0' || LOOK()>'8') return c; c=c*8+(GETC()-'0'); if(LOOK()<'0' || LOOK()>'8') return c; c=c*8+(GETC()-'0'); return c; case 'r': return '\r'; case 'n': return '\n'; case 't': return '\t'; case 'b': return '\b'; case '\n': lex.current_line++; return '\n'; case 'x': switch(LOOK()) { default: return c; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': c=GETC()-'0'; break; case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': c=GETC()-'a'+10; break; case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': c=GETC()-'A'+10; break; } switch(LOOK()) { default: return c; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': c=c*16+GETC()-'0'; break; case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': c=c*16+GETC()-'a'+10; break; case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': c=c*16+GETC()-'a'+10; break; } return c;
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  return c;
5267b71995-08-09Fredrik Hübinette (Hubbe) }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) static struct pike_string *readstring(void)
5267b71995-08-09Fredrik Hübinette (Hubbe) {
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  int c; dynamic_buffer tmp; initialize_buf(&tmp); while(1)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  switch(c=GETC())
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  case 0: lex.pos--; yyerror("End of file in string."); break; case '\n': lex.current_line++; yyerror("Newline in string."); break; case '\\': low_my_putchar(char_const(),&tmp); continue; case '"': break; default: low_my_putchar(c,&tmp); continue;
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  break;
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  return low_free_buf(&tmp);
5267b71995-08-09Fredrik Hübinette (Hubbe) }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) int yylex(YYSTYPE *yylval) #if LEXDEBUG>4
5267b71995-08-09Fredrik Hübinette (Hubbe) {
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  int t; int yylex2(YYSTYPE *); t=yylex2(yylval); if(t<256)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
aeeef31998-01-16Fredrik Hübinette (Hubbe)  fprintf(stderr,"YYLEX: '%c' (%d) at %s:%d\n",t,t,lex.current_file->str,lex.current_line);
5267b71995-08-09Fredrik Hübinette (Hubbe)  }else{
aeeef31998-01-16Fredrik Hübinette (Hubbe)  fprintf(stderr,"YYLEX: %s (%d) at %s:%d\n",low_get_f_name(t,0),t,lex.current_file->str,lex.current_line);
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  return t;
5267b71995-08-09Fredrik Hübinette (Hubbe) }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) static int yylex2(YYSTYPE *yylval) #endif
5267b71995-08-09Fredrik Hübinette (Hubbe) {
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  INT32 c,len; char *buf;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe) #ifdef __CHECKER__ MEMSET((char *)yylval,0,sizeof(YYSTYPE)); #endif #ifdef MALLOC_DEBUG check_sfltable(); #endif
5267b71995-08-09Fredrik Hübinette (Hubbe) 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  while(1) { switch(c=GETC())
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  case 0: lex.pos--; return 0;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  case '\n': lex.current_line++; continue;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  case '#': SKIPSPACE(); READBUF(C!=' ' && C!='\t' && C!='\n');
5267b71995-08-09Fredrik Hübinette (Hubbe) 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  switch(len>0?buf[0]:0) { char *p; case 'l': if(!ISWORD("line")) goto badhash; READBUF(C!=' ' && C!='\t' && C!='\n'); case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': lex.current_line=atoi(buf)-1; SKIPSPACE(); if(GOBBLE('"')) { struct pike_string *tmp=readstring(); free_string(lex.current_file); lex.current_file=tmp; } break; case 'e': if(ISWORD("error")) { SKIPSPACE(); READBUF(C!='\n'); yyerror(buf); break; } goto badhash;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  case 'p': if(ISWORD("pragma")) { SKIPSPACE(); READBUF(C!='\n'); if (strcmp(buf, "all_inline") == 0) {
61e9a01998-01-25Fredrik Hübinette (Hubbe)  lex.pragmas |= ID_INLINE; } else if (strcmp(buf, "all_nomask") == 0) { lex.pragmas |= ID_NOMASK;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  } break; } badhash: my_yyerror("Unknown directive #%s.",buf); SKIPUPTO('\n'); continue; } continue;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  case ' ': case '\t': continue;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  case '\'': switch(c=GETC()) { case 0: lex.pos--; yyerror("Unexpected end of file\n"); break;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  case '\\': c=char_const(); } if(!GOBBLE('\'')) yyerror("Unterminated character constant."); yylval->number=c; return F_NUMBER; case '"': yylval->string=readstring(); return F_STRING; case ':': if(GOBBLE(':')) return F_COLON_COLON; return c;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  case '.': if(GOBBLE('.'))
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(GOBBLE('.')) return F_DOT_DOT_DOT; return F_DOT_DOT;
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  return c; case '0': if(GOBBLE('x') || GOBBLE('X')) { yylval->number=STRTOL(lex.pos, &lex.pos, 16); return F_NUMBER; } case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  char *p1, *p2; double f; long l; lex.pos--; f=my_strtod(lex.pos, &p1); l=STRTOL(lex.pos, &p2, 0); if(p1>p2)
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  lex.pos=p1; yylval->fnum=(float)f; return F_FLOAT; }else{ lex.pos=p2; yylval->number=l; return F_NUMBER;
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  case '-': if(GOBBLE('=')) return F_SUB_EQ; if(GOBBLE('>')) return F_ARROW; if(GOBBLE('-')) return F_DEC; return '-'; case '+': if(GOBBLE('=')) return F_ADD_EQ; if(GOBBLE('+')) return F_INC; return '+'; case '&': if(GOBBLE('=')) return F_AND_EQ; if(GOBBLE('&')) return F_LAND; return '&'; case '|': if(GOBBLE('=')) return F_OR_EQ; if(GOBBLE('|')) return F_LOR; return '|'; case '^': if(GOBBLE('=')) return F_XOR_EQ; return '^'; case '*': if(GOBBLE('=')) return F_MULT_EQ; return '*'; case '%': if(GOBBLE('=')) return F_MOD_EQ; return '%'; case '/': if(GOBBLE('=')) return F_DIV_EQ; return '/'; case '=': if(GOBBLE('=')) return F_EQ; return '='; case '<': if(GOBBLE('<'))
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(GOBBLE('=')) return F_LSH_EQ; return F_LSH;
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(GOBBLE('=')) return F_LE; return '<'; case '>': if(GOBBLE(')')) return F_MULTISET_END; if(GOBBLE('=')) return F_GE; if(GOBBLE('>'))
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(GOBBLE('=')) return F_RSH_EQ; return F_RSH;
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  return '>';
5267b71995-08-09Fredrik Hübinette (Hubbe) 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  case '!': if(GOBBLE('=')) return F_NE; return F_NOT;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  case '(': if(GOBBLE('<')) return F_MULTISET_START; return '(';
5267b71995-08-09Fredrik Hübinette (Hubbe) 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  case '?': case ',': case '~': case '@': case ')': case '[': case ']': case '{': case ';': case '}': return c;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  case '`':
06983f1996-09-22Fredrik Hübinette (Hubbe)  {
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  char *tmp; int offset=2; if(GOBBLE('`')) offset--; if(GOBBLE('`')) offset--; switch(GETC()) { case '+': tmp="```+"; break; case '/': tmp="```/"; break; case '%': tmp="```%"; break; case '*': tmp="```*"; break; case '&': tmp="```&"; break; case '|': tmp="```|"; break; case '^': tmp="```^"; break; case '~': tmp="```~"; break; case '<': if(GOBBLE('<')) { tmp="```<<"; break; } if(GOBBLE('=')) { tmp="```<="; break; } tmp="```<"; break;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  case '>': if(GOBBLE('>')) { tmp="```>>"; break; } if(GOBBLE('=')) { tmp="```>="; break; } tmp="```>"; break;
06983f1996-09-22Fredrik Hübinette (Hubbe) 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  case '!': if(GOBBLE('=')) { tmp="```!="; break; } tmp="```!"; break; case '=': if(GOBBLE('=')) { tmp="```=="; break; } tmp="```="; break; case '(': if(GOBBLE(')'))
5267b71995-08-09Fredrik Hübinette (Hubbe)  {
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  tmp="```()"; break;
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  yyerror("Illegal ` identifier."); tmp="``"; break; case '-': if(GOBBLE('>')) { tmp="```->"; if(GOBBLE('=')) tmp="```->="; }else{ tmp="```-"; } break;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  case '[': if(GOBBLE(']')) { tmp="```[]"; if(GOBBLE('=')) tmp="```[]="; break; }
5267b71995-08-09Fredrik Hübinette (Hubbe) 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  default: yyerror("Illegal ` identifier."); lex.pos--; tmp="``"; break; }
5267b71995-08-09Fredrik Hübinette (Hubbe) 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  yylval->string=make_shared_string(tmp+offset); return F_IDENTIFIER;
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
06983f1996-09-22Fredrik Hübinette (Hubbe) 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  default: if(isidchar(c)) { struct pike_string *s; lex.pos--; READBUF(isidchar(C));
5267b71995-08-09Fredrik Hübinette (Hubbe) 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  yylval->number=lex.current_line;
5267b71995-08-09Fredrik Hübinette (Hubbe) 
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  if(len>1 && len<10) { switch(TWO_CHAR(buf[0],buf[1])) { case TWO_CHAR('a','r'): if(ISWORD("array")) return F_ARRAY_ID;
c2c0521997-09-07Fredrik Hübinette (Hubbe)  break;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  case TWO_CHAR('b','r'): if(ISWORD("break")) return F_BREAK;
c2c0521997-09-07Fredrik Hübinette (Hubbe)  break;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  case TWO_CHAR('c','a'): if(ISWORD("case")) return F_CASE; if(ISWORD("catch")) return F_CATCH;
c2c0521997-09-07Fredrik Hübinette (Hubbe)  break;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  case TWO_CHAR('c','l'): if(ISWORD("class")) return F_CLASS;
c2c0521997-09-07Fredrik Hübinette (Hubbe)  break;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  case TWO_CHAR('c','o'): if(ISWORD("constant")) return F_CONSTANT; if(ISWORD("continue")) return F_CONTINUE;
c2c0521997-09-07Fredrik Hübinette (Hubbe)  break;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  case TWO_CHAR('d','e'): if(ISWORD("default")) return F_DEFAULT;
c2c0521997-09-07Fredrik Hübinette (Hubbe)  break;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  case TWO_CHAR('d','o'): if(ISWORD("do")) return F_DO;
5267b71995-08-09Fredrik Hübinette (Hubbe)  break;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  case TWO_CHAR('e','l'): if(ISWORD("else")) return F_ELSE;
5267b71995-08-09Fredrik Hübinette (Hubbe)  break;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  case TWO_CHAR('f','l'): if(ISWORD("float")) return F_FLOAT_ID;
5267b71995-08-09Fredrik Hübinette (Hubbe)  break;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  case TWO_CHAR('f','o'): if(ISWORD("for")) return F_FOR; if(ISWORD("foreach")) return F_FOREACH;
5267b71995-08-09Fredrik Hübinette (Hubbe)  break;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  case TWO_CHAR('f','u'): if(ISWORD("function")) return F_FUNCTION_ID;
5267b71995-08-09Fredrik Hübinette (Hubbe)  break;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  case TWO_CHAR('g','a'): if(ISWORD("gauge")) return F_GAUGE;
5267b71995-08-09Fredrik Hübinette (Hubbe)  break;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  case TWO_CHAR('i','f'): if(ISWORD("if")) return F_IF; break; case TWO_CHAR('i','m'): if(ISWORD("import")) return F_IMPORT; break; case TWO_CHAR('i','n'): if(ISWORD("int")) return F_INT_ID; if(ISWORD("inherit")) return F_INHERIT; if(ISWORD("inline")) return F_INLINE; break; case TWO_CHAR('l','a'): if(ISWORD("lambda")) return F_LAMBDA; break; case TWO_CHAR('m','a'): if(ISWORD("mapping")) return F_MAPPING_ID; break; case TWO_CHAR('m','i'): if(ISWORD("mixed")) return F_MIXED_ID; break; case TWO_CHAR('m','u'): if(ISWORD("multiset")) return F_MULTISET_ID; break; case TWO_CHAR('n','o'): if(ISWORD("nomask")) return F_NO_MASK; break; case TWO_CHAR('o','b'): if(ISWORD("object")) return F_OBJECT_ID; break; case TWO_CHAR('p','r'): if(ISWORD("predef")) return F_PREDEF; if(ISWORD("program")) return F_PROGRAM_ID; if(ISWORD("private")) return F_PRIVATE; if(ISWORD("protected")) return F_PROTECTED;
5267b71995-08-09Fredrik Hübinette (Hubbe)  break; break;
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  case TWO_CHAR('p','u'): if(ISWORD("public")) return F_PUBLIC; break; case TWO_CHAR('r','e'): if(ISWORD("return")) return F_RETURN; break; case TWO_CHAR('s','s'): if(ISWORD("sscanf")) return F_SSCANF; break; case TWO_CHAR('s','t'): if(ISWORD("static")) return F_STATIC; if(ISWORD("string")) return F_STRING_ID; break; case TWO_CHAR('s','w'): if(ISWORD("switch")) return F_SWITCH; break; case TWO_CHAR('t','y'): if(ISWORD("typeof")) return F_TYPEOF; break; case TWO_CHAR('v','o'): if(ISWORD("void")) return F_VOID_ID; break; case TWO_CHAR('w','h'): if(ISWORD("while")) return F_WHILE; break; }
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  yylval->string=make_shared_binary_string(buf,len); return F_IDENTIFIER;
5267b71995-08-09Fredrik Hübinette (Hubbe)  }else{
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  char buff[100]; sprintf(buff, "Illegal character (hex %02x) '%c'", c, c); yyerror(buff); return ' ';
5267b71995-08-09Fredrik Hübinette (Hubbe)  }
b1f4eb1998-01-13Fredrik Hübinette (Hubbe)  } } } }
5267b71995-08-09Fredrik Hübinette (Hubbe)