Changeset 798 in webkit for trunk/JavaScriptCore/kjs/lexer.cpp


Ignore:
Timestamp:
Mar 21, 2002, 4:31:57 PM (23 years ago)
Author:
mjs
Message:

Merged changes from LABYRINTH_KDE_3_MERGE branch.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/kjs/lexer.cpp

    r6 r798  
     1// -*- c-basic-offset: 2 -*-
    12/*
    23 *  This file is part of the KDE libraries
     
    1718 *  the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    1819 *  Boston, MA 02111-1307, USA.
     20 *
     21 *  $Id$
    1922 */
    2023
     
    2932#include <assert.h>
    3033
    31 #include "kjs.h"
     34#include "value.h"
     35#include "object.h"
     36#include "types.h"
     37#include "interpreter.h"
    3238#include "nodes.h"
    3339#include "lexer.h"
     
    3945using namespace KJS;
    4046
     47static Lexer *currLexer = 0;
     48
    4149#ifndef KDE_USE_FINAL
    4250#include "grammar.h"
     
    4553#include "lexer.lut.h"
    4654
    47 #ifdef KJS_DEBUGGER
    4855extern YYLTYPE yylloc;  // global bison variable holding token info
    49 #endif
    5056
    5157// a bridge for yacc from the C world to C++
     
    5864  : yylineno(0),
    5965    size8(128), size16(128), restrKeyword(false),
    60     stackToken(-1), pos(0),
     66    eatNextIdentifier(false), stackToken(-1), lastToken(-1), pos(0),
    6167    code(0), length(0),
    6268#ifndef KJS_PURE_ECMA
     
    6874  buffer8 = new char[size8];
    6975  buffer16 = new UChar[size16];
     76  currLexer = this;
    7077
    7178}
     
    7986Lexer *Lexer::curr()
    8087{
    81   assert(KJScriptImp::current());
    82   return KJScriptImp::current()->lex;
     88  if (!currLexer) {
     89    // create singleton instance
     90    currLexer = new Lexer();
     91  }
     92  return currLexer;
    8393}
    8494
     
    8898  restrKeyword = false;
    8999  delimited = false;
     100  eatNextIdentifier = false;
    90101  stackToken = -1;
     102  lastToken = -1;
    91103  pos = 0;
    92104  code = c;
    93105  length = len;
     106  skipLF = false;
     107  skipCR = false;
    94108#ifndef KJS_PURE_ECMA
    95109  bol = true;
     
    128142  done = false;
    129143  terminator = false;
     144  skipLF = false;
     145  skipCR = false;
    130146
    131147  // did we push a token on the stack previously ?
     
    138154
    139155  while (!done) {
     156    if (skipLF && current != '\n') // found \r but not \n afterwards
     157        skipLF = false;
     158    if (skipCR && current != '\r') // found \n but not \r afterwards
     159        skipCR = false;
     160    if (skipLF || skipCR) // found \r\n or \n\r -> eat the second one
     161    {
     162        skipLF = false;
     163        skipCR = false;
     164        shift(1);
     165    }
    140166    switch (state) {
    141167    case Start:
     
    316342        record8(current);
    317343        state = InOctal;
     344      } else if (isDecimalDigit(current)) {
     345        record8(current);
     346        state = InDecimal;
    318347      } else {
    319348        setDone(Number);
     
    330359      if (isOctalDigit(current)) {
    331360        record8(current);
     361      }
     362      else if (isDecimalDigit(current)) {
     363        record8(current);
     364        state = InDecimal;
    332365      } else
    333366        setDone(Octal);
     
    434467#endif
    435468
     469  if (state != Identifier && eatNextIdentifier)
     470    eatNextIdentifier = false;
     471
    436472  restrKeyword = false;
    437473  delimited = false;
    438 #ifdef KJS_DEBUGGER
    439474  yylloc.first_line = yylineno; // ???
    440475  yylloc.last_line = yylineno;
    441 #endif
    442476
    443477  switch (state) {
    444478  case Eof:
    445     return 0;
     479    token = 0;
     480    break;
    446481  case Other:
    447482    if(token == '}' || token == ';') {
    448483      delimited = true;
    449484    }
    450     return token;
     485    break;
    451486  case Identifier:
    452487    if ((token = Lookup::find(&mainTable, buffer16, pos16)) < 0) {
     488      // Lookup for keyword failed, means this is an identifier
     489      // Apply anonymous-function hack below (eat the identifier)
     490      if (eatNextIdentifier) {
     491        eatNextIdentifier = false;
     492        UString debugstr(buffer16, pos16); fprintf(stderr,"Anonymous function hack: eating identifier %s\n",debugstr.ascii());
     493        token = lex();
     494        break;
     495      }
    453496      /* TODO: close leak on parse error. same holds true for String */
    454497      kjsyylval.ustr = new UString(buffer16, pos16);
    455       return IDENT;
     498      token = IDENT;
     499      break;
    456500    }
     501
     502    eatNextIdentifier = false;
     503    // Hack for "f = function somename() { ... }", too hard to get into the grammar
     504    if (token == FUNCTION && lastToken == '=' )
     505      eatNextIdentifier = true;
     506
    457507    if (token == CONTINUE || token == BREAK ||
    458508        token == RETURN || token == THROW)
    459509      restrKeyword = true;
    460     return token;
     510    break;
    461511  case String:
    462     kjsyylval.ustr = new UString(buffer16, pos16); return STRING;
     512    kjsyylval.ustr = new UString(buffer16, pos16);
     513    token = STRING;
     514    break;
    463515  case Number:
    464516    kjsyylval.dval = dval;
    465     return NUMBER;
     517    token = NUMBER;
     518    break;
    466519  case Bad:
    467520    fprintf(stderr, "yylex: ERROR.\n");
     
    471524    return -1;
    472525  }
     526  lastToken = token;
     527  return token;
    473528}
    474529
     
    479534}
    480535
    481 bool Lexer::isLineTerminator() const
    482 {
    483   return (current == '\n' || current == '\r');
     536bool Lexer::isLineTerminator()
     537{
     538  bool cr = (current == '\r');
     539  bool lf = (current == '\n');
     540  if (cr)
     541      skipLF = true;
     542  else if (lf)
     543      skipCR = true;
     544  return cr || lf;
    484545}
    485546
     
    541602  } else if (c1 == '+' && c2 == '+') {
    542603    shift(2);
    543     if (terminator) {
    544       // automatic semicolon insertion
    545       stackToken = PLUSPLUS;
    546       return AUTO;
    547     } else
     604    if (terminator)
     605      return AUTOPLUSPLUS;
     606    else
    548607      return PLUSPLUS;
    549608  } else if (c1 == '-' && c2 == '-') {
    550609    shift(2);
    551     if (terminator) {
    552       // automatic semicolon insertion
    553       stackToken = MINUSMINUS;
    554       return AUTO;
    555     } else
     610    if (terminator)
     611      return AUTOMINUSMINUS;
     612    else
    556613      return MINUSMINUS;
    557614  } else if (c1 == '=' && c2 == '=') {
     
    716773  pos16 = 0;
    717774  bool lastWasEscape = false;
     775  bool inBrackets = false;
    718776
    719777  while (1) {
    720778    if (isLineTerminator() || current == 0)
    721779      return false;
    722     else if (current != '/' || lastWasEscape == true)
     780    else if (current != '/' || lastWasEscape == true || inBrackets == true)
    723781    {
     782        // keep track of '[' and ']'
     783        if ( !lastWasEscape ) {
     784          if ( current == '[' && !inBrackets )
     785            inBrackets = true;
     786          if ( current == ']' && inBrackets )
     787            inBrackets = false;
     788        }
    724789        record16(current);
    725790        lastWasEscape =
    726791            !lastWasEscape && (current == '\\');
    727792    }
    728     else {
     793    else { // end of regexp
    729794      pattern = UString(buffer16, pos16);
    730795      pos16 = 0;
Note: See TracChangeset for help on using the changeset viewer.