зеркало из https://github.com/mozilla/pjs.git
Updated parser: attributes can be expressions, added new attributes, disallowed nested ::'s, deleted Eval nodes, added const and void nodes, deleted package attribute, deleted super::id syntax, and added super, super(expr), and super(args) syntax
This commit is contained in:
Родитель
8e0358e13a
Коммит
c3cb31ba54
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -13,11 +13,11 @@
|
|||
* The Original Code is the JavaScript 2 Prototype.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU Public License (the "GPL"), in which case the
|
||||
|
@ -43,7 +43,7 @@
|
|||
#include "utilities.h"
|
||||
#include "strings.h"
|
||||
|
||||
namespace JavaScript
|
||||
namespace JavaScript
|
||||
{
|
||||
//
|
||||
// Output
|
||||
|
@ -51,332 +51,271 @@ namespace JavaScript
|
|||
|
||||
// Print the characters between begin and end to the given file. These
|
||||
// characters may include nulls.
|
||||
size_t printChars(FILE *file, const char *begin, const char *end);
|
||||
size_t printChars(FILE *file, const char *begin, const char *end);
|
||||
|
||||
#ifndef XP_MAC_MPW
|
||||
inline size_t printChars(FILE *file, const char *begin, const char *end) {
|
||||
ASSERT(end >= begin);
|
||||
return STD::fwrite(begin, 1, static_cast<size_t>(end - begin), file);
|
||||
}
|
||||
inline size_t printChars(FILE *file, const char *begin, const char *end) {
|
||||
ASSERT(end >= begin);
|
||||
return STD::fwrite(begin, 1, static_cast<size_t>(end - begin), file);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// A Formatter is an abstract base class representing a simplified output stream.
|
||||
// One can print text to a Formatter by using << and the various global
|
||||
// print... methods below. Formatters accept both char and char16 text and
|
||||
// convert as appropriate to their actual stream.
|
||||
class Formatter {
|
||||
protected:
|
||||
virtual void printChar8(char ch);
|
||||
virtual void printChar16(char16 ch);
|
||||
virtual void printZStr8(const char *str);
|
||||
virtual void printStr8(const char *strBegin, const char *strEnd) = 0;
|
||||
virtual void printStr16(const char16 *strBegin,
|
||||
const char16 *strEnd) = 0;
|
||||
virtual void printString16(const String &s);
|
||||
virtual void printVFormat8(const char *format, va_list args);
|
||||
public:
|
||||
|
||||
Formatter &operator<<(char ch) {printChar8(ch); return *this;}
|
||||
Formatter &operator<<(char16 ch) {printChar16(ch); return *this;}
|
||||
Formatter &operator<<(const char *str) {printZStr8(str); return *this;}
|
||||
Formatter &operator<<(const String &s) {printString16(s); return *this;}
|
||||
Formatter &operator<<(uint32 i) {
|
||||
printFormat(*this, "%u", i);
|
||||
return *this;
|
||||
}
|
||||
class Formatter {
|
||||
protected:
|
||||
virtual void printChar8(char ch);
|
||||
virtual void printChar16(char16 ch);
|
||||
virtual void printZStr8(const char *str);
|
||||
virtual void printStr8(const char *strBegin, const char *strEnd) = 0;
|
||||
virtual void printStr16(const char16 *strBegin, const char16 *strEnd) = 0;
|
||||
virtual void printString16(const String &s);
|
||||
virtual void printVFormat8(const char *format, va_list args);
|
||||
public:
|
||||
|
||||
friend void printString(Formatter &f, const char *strBegin,
|
||||
const char *strEnd) {
|
||||
f.printStr8(strBegin, strEnd);
|
||||
}
|
||||
Formatter &operator<<(char ch) {printChar8(ch); return *this;}
|
||||
Formatter &operator<<(char16 ch) {printChar16(ch); return *this;}
|
||||
Formatter &operator<<(const char *str) {printZStr8(str); return *this;}
|
||||
Formatter &operator<<(const String &s) {printString16(s); return *this;}
|
||||
Formatter &operator<<(uint32 i) {
|
||||
printFormat(*this, "%u", i);
|
||||
return *this;
|
||||
}
|
||||
|
||||
friend void printString(Formatter &f, const char16 *strBegin,
|
||||
const char16 *strEnd) {
|
||||
f.printStr16(strBegin, strEnd);
|
||||
}
|
||||
|
||||
friend void printFormat(Formatter &f, const char *format, ...) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
f.printVFormat8(format, args);
|
||||
va_end(args);
|
||||
}
|
||||
};
|
||||
|
||||
void printNum(Formatter &f, uint32 i, int nDigits, char pad,
|
||||
const char *format);
|
||||
void printChar(Formatter &f, char ch, int count);
|
||||
void printChar(Formatter &f, char16 ch, int count);
|
||||
friend void printString(Formatter &f, const char *strBegin, const char *strEnd) {
|
||||
f.printStr8(strBegin, strEnd);
|
||||
}
|
||||
|
||||
inline void printDec(Formatter &f, int32 i, int nDigits = 0,
|
||||
char pad = ' ') {
|
||||
printNum(f, (uint32)i, nDigits, pad, "%i");
|
||||
}
|
||||
|
||||
inline void printDec(Formatter &f, uint32 i, int nDigits = 0,
|
||||
char pad = ' ') {
|
||||
printNum(f, i, nDigits, pad, "%u");
|
||||
}
|
||||
|
||||
inline void printHex(Formatter &f, int32 i, int nDigits = 0,
|
||||
char pad = '0') {
|
||||
printNum(f, (uint32)i, nDigits, pad, "%X");
|
||||
}
|
||||
|
||||
inline void printHex(Formatter &f, uint32 i, int nDigits = 0,
|
||||
char pad = '0') {
|
||||
printNum(f, i, nDigits, pad, "%X");
|
||||
}
|
||||
|
||||
void printPtr(Formatter &f, void *p);
|
||||
friend void printString(Formatter &f, const char16 *strBegin, const char16 *strEnd) {
|
||||
f.printStr16(strBegin, strEnd);
|
||||
}
|
||||
|
||||
friend void printFormat(Formatter &f, const char *format, ...) {
|
||||
va_list args;
|
||||
va_start(args, format);
|
||||
f.printVFormat8(format, args);
|
||||
va_end(args);
|
||||
}
|
||||
};
|
||||
|
||||
void printNum(Formatter &f, uint32 i, int nDigits, char pad, const char *format);
|
||||
void printChar(Formatter &f, char ch, int count);
|
||||
void printChar(Formatter &f, char16 ch, int count);
|
||||
inline void printDec(Formatter &f, int32 i, int nDigits = 0, char pad = ' ') {printNum(f, (uint32)i, nDigits, pad, "%i");}
|
||||
inline void printDec(Formatter &f, uint32 i, int nDigits = 0, char pad = ' ') {printNum(f, i, nDigits, pad, "%u");}
|
||||
inline void printHex(Formatter &f, int32 i, int nDigits = 0, char pad = '0') {printNum(f, (uint32)i, nDigits, pad, "%X");}
|
||||
inline void printHex(Formatter &f, uint32 i, int nDigits = 0, char pad = '0') {printNum(f, i, nDigits, pad, "%X");}
|
||||
void printPtr(Formatter &f, void *p);
|
||||
|
||||
|
||||
// An AsciiFileFormatter is a Formatter that prints to a standard ASCII
|
||||
// file or stream. Characters with Unicode values of 256 or higher are
|
||||
// converted to escape sequences. Selected lower characters can also be
|
||||
// converted to escape sequences; these are specified by set bits in the
|
||||
// BitSet passed to the constructor.
|
||||
class AsciiFileFormatter: public Formatter {
|
||||
FILE *file;
|
||||
BitSet<256> filter; // Set of first 256 characters that are to be
|
||||
// converted to escape sequences
|
||||
bool filterEmpty; // True if filter passes all 256 characters
|
||||
public:
|
||||
static BitSet<256> defaultFilter; // Default value of filter when not
|
||||
// given in the constructor
|
||||
|
||||
explicit AsciiFileFormatter(FILE *file, BitSet<256> *filter = 0);
|
||||
// An AsciiFileFormatter is a Formatter that prints to a standard ASCII
|
||||
// file or stream. Characters with Unicode values of 256 or higher are
|
||||
// converted to escape sequences. Selected lower characters can also be
|
||||
// converted to escape sequences; these are specified by set bits in the
|
||||
// BitSet passed to the constructor.
|
||||
class AsciiFileFormatter: public Formatter {
|
||||
FILE *file;
|
||||
BitSet<256> filter; // Set of first 256 characters that are to be converted to escape sequences
|
||||
bool filterEmpty; // True if filter passes all 256 characters
|
||||
public:
|
||||
static BitSet<256> defaultFilter; // Default value of filter when not given in the constructor
|
||||
|
||||
private:
|
||||
bool filterChar(char ch) {return filter[static_cast<uchar>(ch)];}
|
||||
bool filterChar(char16 ch) {
|
||||
return char16Value(ch) >= 0x100 || filter[char16Value(ch)];
|
||||
}
|
||||
|
||||
protected:
|
||||
void printChar8(char ch);
|
||||
void printChar16(char16 ch);
|
||||
void printZStr8(const char *str);
|
||||
void printStr8(const char *strBegin, const char *strEnd);
|
||||
void printStr16(const char16 *strBegin, const char16 *strEnd);
|
||||
};
|
||||
explicit AsciiFileFormatter(FILE *file, BitSet<256> *filter = 0);
|
||||
|
||||
extern AsciiFileFormatter stdOut;
|
||||
extern AsciiFileFormatter stdErr;
|
||||
private:
|
||||
bool filterChar(char ch) {return filter[static_cast<uchar>(ch)];}
|
||||
bool filterChar(char16 ch) {
|
||||
return char16Value(ch) >= 0x100 || filter[char16Value(ch)];
|
||||
}
|
||||
|
||||
protected:
|
||||
void printChar8(char ch);
|
||||
void printChar16(char16 ch);
|
||||
void printZStr8(const char *str);
|
||||
void printStr8(const char *strBegin, const char *strEnd);
|
||||
void printStr16(const char16 *strBegin, const char16 *strEnd);
|
||||
};
|
||||
|
||||
extern AsciiFileFormatter stdOut;
|
||||
extern AsciiFileFormatter stdErr;
|
||||
|
||||
|
||||
// A StringFormatter is a Formatter that prints to a String.
|
||||
class StringFormatter: public Formatter {
|
||||
String s;
|
||||
// A StringFormatter is a Formatter that prints to a String.
|
||||
class StringFormatter: public Formatter {
|
||||
String s;
|
||||
|
||||
public:
|
||||
const String& getString() { return s; }
|
||||
void clear() {JavaScript::clear(s);}
|
||||
protected:
|
||||
void printChar8(char ch);
|
||||
void printChar16(char16 ch);
|
||||
void printZStr8(const char *str);
|
||||
void printStr8(const char *strBegin, const char *strEnd);
|
||||
void printStr16(const char16 *strBegin, const char16 *strEnd);
|
||||
void printString16(const String &str);
|
||||
};
|
||||
public:
|
||||
const String& getString() { return s; }
|
||||
void clear() {JavaScript::clear(s);}
|
||||
protected:
|
||||
void printChar8(char ch);
|
||||
void printChar16(char16 ch);
|
||||
void printZStr8(const char *str);
|
||||
void printStr8(const char *strBegin, const char *strEnd);
|
||||
void printStr16(const char16 *strBegin, const char16 *strEnd);
|
||||
void printString16(const String &str);
|
||||
};
|
||||
|
||||
|
||||
//
|
||||
// Formatted Output
|
||||
//
|
||||
|
||||
class PrettyPrinter: public Formatter {
|
||||
public:
|
||||
STATIC_CONST(uint32, unlimitedLineWidth = 0x7FFFFFFF);
|
||||
class Region;
|
||||
class Indent;
|
||||
class Block;
|
||||
class PrettyPrinter: public Formatter {
|
||||
public:
|
||||
STATIC_CONST(uint32, unlimitedLineWidth = 0x7FFFFFFF);
|
||||
class Region;
|
||||
class Indent;
|
||||
class Block;
|
||||
|
||||
private:
|
||||
STATIC_CONST(uint32, infiniteLength = 0x80000000);
|
||||
const uint32 lineWidth; // Current maximum desired line width
|
||||
private:
|
||||
STATIC_CONST(uint32, infiniteLength = 0x80000000);
|
||||
const uint32 lineWidth; // Current maximum desired line width
|
||||
|
||||
struct BlockInfo {
|
||||
uint32 margin; // Saved margin before this block's beginning
|
||||
uint32 lastBreak; // Saved lastBreak before this block's beginning
|
||||
bool fits; // True if this entire block fits on one line
|
||||
};
|
||||
// Variables for the back end that prints to the destination
|
||||
Formatter &outputFormatter; // Destination formatter on which the
|
||||
// result should be printed
|
||||
uint32 outputPos; // Number of characters printed on current
|
||||
// output line
|
||||
uint32 lineNum; // Serial number of current line
|
||||
uint32 lastBreak; // Number of line just after the last
|
||||
// break that occurred in this block
|
||||
uint32 margin; // Current left margin in spaces
|
||||
ArrayBuffer<BlockInfo, 20> savedBlocks; // Stack of saved information
|
||||
// about partially printed blocks
|
||||
struct BlockInfo {
|
||||
uint32 margin; // Saved margin before this block's beginning
|
||||
uint32 lastBreak; // Saved lastBreak before this block's beginning
|
||||
bool fits; // True if this entire block fits on one line
|
||||
};
|
||||
|
||||
// Variables for the front end that calculates block sizes
|
||||
struct Item: ListQueueEntry {
|
||||
enum Kind {text, blockBegin, indentBlockBegin, blockEnd, indent,
|
||||
linearBreak, fillBreak};
|
||||
// Variables for the back end that prints to the destination
|
||||
Formatter &outputFormatter; // Destination formatter on which the result should be printed
|
||||
uint32 outputPos; // Number of characters printed on current output line
|
||||
uint32 lineNum; // Serial number of current line
|
||||
uint32 lastBreak; // Number of line just after the last break that occurred in this block
|
||||
uint32 margin; // Current left margin in spaces
|
||||
ArrayBuffer<BlockInfo, 20> savedBlocks; // Stack of saved information about partially printed blocks
|
||||
|
||||
const Kind kind; // The kind of this text sequence
|
||||
bool lengthKnown; // True if totalLength is known; always true for
|
||||
// text, blockEnd, and indent Items
|
||||
uint32 length; // Length of this text sequence, number of spaces
|
||||
// for this break, or delta for indent or
|
||||
// indentBlockBegin
|
||||
uint32 totalLength; // Total length of this block (for blockBegin)
|
||||
// or length of this break plus following clump
|
||||
// (for breaks)
|
||||
// If lengthKnown is false, this is the
|
||||
// serialPos of this Item instead of a length
|
||||
bool hasKind(Kind k) const {return kind == k;}
|
||||
|
||||
explicit Item(Kind kind) :
|
||||
kind(kind), lengthKnown(true) {}
|
||||
Item(Kind kind, uint32 length) :
|
||||
kind(kind), lengthKnown(true), length(length) {}
|
||||
Item(Kind kind, uint32 length, uint32 beginSerialPos):
|
||||
kind(kind), lengthKnown(false), length(length),
|
||||
totalLength(beginSerialPos) {}
|
||||
|
||||
void computeTotalLength(uint32 endSerialPos) {
|
||||
ASSERT(!lengthKnown);
|
||||
lengthKnown = true;
|
||||
totalLength = endSerialPos - totalLength;
|
||||
}
|
||||
|
||||
};
|
||||
// Variables for the front end that calculates block sizes
|
||||
struct Item: ListQueueEntry {
|
||||
enum Kind {text, blockBegin, indentBlockBegin, blockEnd, indent, linearBreak, fillBreak};
|
||||
|
||||
const Kind kind; // The kind of this text sequence
|
||||
bool lengthKnown; // True if totalLength is known; always true for text, blockEnd, and indent Items
|
||||
uint32 length; // Length of this text sequence, number of spaces for this break, or delta for indent or indentBlockBegin
|
||||
uint32 totalLength; // Total length of this block (for blockBegin) or length of this break plus following clump (for breaks);
|
||||
// If lengthKnown is false, this is the serialPos of this Item instead of a length
|
||||
bool hasKind(Kind k) const {return kind == k;}
|
||||
|
||||
explicit Item(Kind kind): kind(kind), lengthKnown(true) {}
|
||||
Item(Kind kind, uint32 length): kind(kind), lengthKnown(true), length(length) {}
|
||||
Item(Kind kind, uint32 length, uint32 beginSerialPos):
|
||||
kind(kind), lengthKnown(false), length(length), totalLength(beginSerialPos) {}
|
||||
|
||||
void computeTotalLength(uint32 endSerialPos) {
|
||||
ASSERT(!lengthKnown);
|
||||
lengthKnown = true;
|
||||
totalLength = endSerialPos - totalLength;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#ifdef DEBUG
|
||||
Region *topRegion; // Most deeply nested Region
|
||||
Region *topRegion; // Most deeply nested Region
|
||||
#endif
|
||||
uint32 nNestedBlocks; // Number of nested Blocks
|
||||
|
||||
uint32 leftSerialPos; // The difference rightSerialPos-
|
||||
uint32 rightSerialPos; // leftSerialPos is always the number of
|
||||
// characters that would be output by
|
||||
// printing activeItems if they all fit
|
||||
// on one line; only the difference
|
||||
// matters -- the absolute values are
|
||||
// irrelevant and may wrap around 2^32.
|
||||
|
||||
ArrayQueue<Item *, 20> itemStack; // Stack of enclosing nested Items
|
||||
// whose lengths have not yet been
|
||||
// determined itemStack always has
|
||||
// room for at least nNestedBlocks
|
||||
// extra entries so that end Items
|
||||
// may be added without throwing an
|
||||
// exception.
|
||||
|
||||
Pool<Item> itemPool; // Pool from which to allocate
|
||||
// activeItems
|
||||
|
||||
ListQueue<Item> activeItems; // Queue of items left to be printed
|
||||
|
||||
ArrayQueue<char16, 256> itemText; // Text of text items in activeItems,
|
||||
// in the same order as in activeItems
|
||||
uint32 nNestedBlocks; // Number of nested Blocks
|
||||
|
||||
public:
|
||||
static uint32 defaultLineWidth; // Default for lineWidth if not given
|
||||
// to the constructor
|
||||
uint32 leftSerialPos; // The difference rightSerialPos-
|
||||
uint32 rightSerialPos; // leftSerialPos is always the number of characters that would be output by
|
||||
// printing activeItems if they all fit on one line; only the difference
|
||||
// matters -- the absolute values are irrelevant and may wrap around 2^32.
|
||||
|
||||
explicit PrettyPrinter(Formatter &f,
|
||||
uint32 lineWidth = defaultLineWidth);
|
||||
private:
|
||||
PrettyPrinter(const PrettyPrinter&); // No copy constructor
|
||||
void operator=(const PrettyPrinter&); // No assignment operator
|
||||
public:
|
||||
~PrettyPrinter();
|
||||
|
||||
private:
|
||||
void outputBreak(bool sameLine, uint32 nSpaces);
|
||||
bool reduceLeftActiveItems(uint32 rightOffset);
|
||||
void reduceRightActiveItems();
|
||||
ArrayQueue<Item *, 20> itemStack; // Stack of enclosing nested Items whose lengths have not yet been determined;
|
||||
// itemStack always has room for at least nNestedBlocks extra entries so that end Items
|
||||
// may be added without throwing an exception.
|
||||
Pool<Item> itemPool; // Pool from which to allocate activeItems
|
||||
ListQueue<Item> activeItems; // Queue of items left to be printed
|
||||
ArrayQueue<char16, 256> itemText; // Text of text items in activeItems, in the same order as in activeItems
|
||||
|
||||
Item &beginIndent(int32 offset);
|
||||
void endIndent(Item &i);
|
||||
public:
|
||||
static uint32 defaultLineWidth; // Default for lineWidth if not given to the constructor
|
||||
|
||||
Item &beginBlock(Item::Kind kind, int32 offset);
|
||||
void endBlock(Item &i);
|
||||
explicit PrettyPrinter(Formatter &f, uint32 lineWidth = defaultLineWidth);
|
||||
private:
|
||||
PrettyPrinter(const PrettyPrinter&); // No copy constructor
|
||||
void operator=(const PrettyPrinter&); // No assignment operator
|
||||
public:
|
||||
~PrettyPrinter();
|
||||
|
||||
void conditionalBreak(uint32 nSpaces, Item::Kind kind);
|
||||
private:
|
||||
void outputBreak(bool sameLine, uint32 nSpaces);
|
||||
bool reduceLeftActiveItems(uint32 rightOffset);
|
||||
void reduceRightActiveItems();
|
||||
|
||||
protected:
|
||||
void printStr8(const char *strBegin, const char *strEnd);
|
||||
void printStr16(const char16 *strBegin, const char16 *strEnd);
|
||||
public:
|
||||
Item &beginIndent(int32 offset);
|
||||
void endIndent(Item &i);
|
||||
|
||||
void requiredBreak();
|
||||
void linearBreak(uint32 nSpaces) {conditionalBreak(nSpaces,
|
||||
Item::linearBreak);}
|
||||
void linearBreak(uint32 nSpaces, bool required);
|
||||
void fillBreak(uint32 nSpaces) {
|
||||
conditionalBreak(nSpaces, Item::fillBreak);
|
||||
}
|
||||
|
||||
void end();
|
||||
Item &beginBlock(Item::Kind kind, int32 offset);
|
||||
void endBlock(Item &i);
|
||||
|
||||
friend class Region;
|
||||
friend class Indent;
|
||||
friend class Block;
|
||||
void conditionalBreak(uint32 nSpaces, Item::Kind kind);
|
||||
|
||||
class Region {
|
||||
protected:
|
||||
void printStr8(const char *strBegin, const char *strEnd);
|
||||
void printStr16(const char16 *strBegin, const char16 *strEnd);
|
||||
public:
|
||||
|
||||
void requiredBreak();
|
||||
void linearBreak(uint32 nSpaces) {conditionalBreak(nSpaces, Item::linearBreak);}
|
||||
void linearBreak(uint32 nSpaces, bool required);
|
||||
void fillBreak(uint32 nSpaces) {conditionalBreak(nSpaces, Item::fillBreak);}
|
||||
|
||||
void end();
|
||||
|
||||
friend class Region;
|
||||
friend class Indent;
|
||||
friend class Block;
|
||||
|
||||
class Region {
|
||||
#ifdef DEBUG
|
||||
Region *next; // Link to next most deeply nested Region
|
||||
Region *next; // Link to next most deeply nested Region
|
||||
#endif
|
||||
protected:
|
||||
PrettyPrinter &pp;
|
||||
protected:
|
||||
PrettyPrinter &pp;
|
||||
|
||||
Region(PrettyPrinter &pp) : pp(pp) {
|
||||
DEBUG_ONLY(next = pp.topRegion; pp.topRegion = this;);
|
||||
}
|
||||
private:
|
||||
Region(const Region&); // No copy constructor
|
||||
void operator=(const Region&); // No assignment operator
|
||||
protected:
|
||||
Region(PrettyPrinter &pp): pp(pp) {DEBUG_ONLY(next = pp.topRegion; pp.topRegion = this;);}
|
||||
private:
|
||||
Region(const Region&); // No copy constructor
|
||||
void operator=(const Region&); // No assignment operator
|
||||
protected:
|
||||
#ifdef DEBUG
|
||||
~Region() {pp.topRegion = next;}
|
||||
~Region() {pp.topRegion = next;}
|
||||
#endif
|
||||
};
|
||||
|
||||
// Use an Indent object to temporarily indent a PrettyPrinter by the
|
||||
// offset given to the Indent's constructor. The PrettyPrinter's margin
|
||||
// is set back to its original value when the Indent object is destroyed.
|
||||
// Using an Indent object is exception-safe; no matter how control
|
||||
// leaves an Indent scope, the indent is undone.
|
||||
// Scopes of Indent and Block objects must be properly nested.
|
||||
class Indent: public Region {
|
||||
Item &endItem; // The Item returned by beginIndent
|
||||
public:
|
||||
Indent(PrettyPrinter &pp, int32 offset) :
|
||||
Region(pp), endItem(pp.beginIndent(offset)) {}
|
||||
~Indent() {pp.endIndent(endItem);}
|
||||
};
|
||||
|
||||
// Use a Block object to temporarily enter a PrettyPrinter block. If an
|
||||
// offset is provided, line breaks inside the block are indented by that
|
||||
// offset relative to the existing indent; otherwise, line breaks inside
|
||||
// the block are indented to the current output position. The block
|
||||
// lasts until the Block object is destroyed.
|
||||
// Scopes of Indent and Block objects must be properly nested.
|
||||
class Block: public Region {
|
||||
Item &endItem; // The Item returned by beginBlock
|
||||
public:
|
||||
explicit Block(PrettyPrinter &pp) :
|
||||
Region(pp), endItem(pp.beginBlock(Item::blockBegin, 0)) {}
|
||||
Block(PrettyPrinter &pp, int32 offset) :
|
||||
Region(pp), endItem(pp.beginBlock(Item::indentBlockBegin,
|
||||
offset)) {}
|
||||
~Block() {pp.endBlock(endItem);}
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
void escapeString(Formatter &f, const char16 *begin, const char16 *end,
|
||||
char16 quote);
|
||||
void quoteString(Formatter &f, const String &s, char16 quote);
|
||||
|
||||
// Use an Indent object to temporarily indent a PrettyPrinter by the
|
||||
// offset given to the Indent's constructor. The PrettyPrinter's margin
|
||||
// is set back to its original value when the Indent object is destroyed.
|
||||
// Using an Indent object is exception-safe; no matter how control
|
||||
// leaves an Indent scope, the indent is undone.
|
||||
// Scopes of Indent and Block objects must be properly nested.
|
||||
class Indent: public Region {
|
||||
Item &endItem; // The Item returned by beginIndent
|
||||
public:
|
||||
Indent(PrettyPrinter &pp, int32 offset): Region(pp), endItem(pp.beginIndent(offset)) {}
|
||||
~Indent() {pp.endIndent(endItem);}
|
||||
};
|
||||
|
||||
// Use a Block object to temporarily enter a PrettyPrinter block. If an
|
||||
// offset is provided, line breaks inside the block are indented by that
|
||||
// offset relative to the existing indent; otherwise, line breaks inside
|
||||
// the block are indented to the current output position. The block
|
||||
// lasts until the Block object is destroyed.
|
||||
// Scopes of Indent and Block objects must be properly nested.
|
||||
class Block: public Region {
|
||||
Item &endItem; // The Item returned by beginBlock
|
||||
public:
|
||||
explicit Block(PrettyPrinter &pp): Region(pp), endItem(pp.beginBlock(Item::blockBegin, 0)) {}
|
||||
Block(PrettyPrinter &pp, int32 offset): Region(pp), endItem(pp.beginBlock(Item::indentBlockBegin, offset)) {}
|
||||
~Block() {pp.endBlock(endItem);}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
void escapeString(Formatter &f, const char16 *begin, const char16 *end, char16 quote);
|
||||
void quoteString(Formatter &f, const String &s, char16 quote);
|
||||
}
|
||||
|
||||
#endif /* formatter_h___ */
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
1186
js2/src/lexer.cpp
1186
js2/src/lexer.cpp
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -17,7 +17,7 @@
|
|||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU Public License (the "GPL"), in which case the
|
||||
|
@ -40,56 +40,39 @@
|
|||
#include "token.h"
|
||||
#include "world.h"
|
||||
|
||||
namespace JavaScript
|
||||
namespace JavaScript
|
||||
{
|
||||
|
||||
class Lexer {
|
||||
enum {tokenLookahead = 2}; // Number of tokens that can be
|
||||
// simultaneously live
|
||||
enum {tokenLookahead = 2}; // Number of tokens that can be simultaneously live
|
||||
#ifdef DEBUG
|
||||
enum {tokenGuard = 10}; // Number of invalid tokens added to
|
||||
// circular token buffer to catch
|
||||
// references to old tokens
|
||||
enum {tokenGuard = 10}; // Number of invalid tokens added to circular token buffer to catch references to old tokens
|
||||
#else
|
||||
enum {tokenGuard = 0}; // Number of invalid tokens added to
|
||||
// circular token buffer to catch
|
||||
// references to old tokens
|
||||
enum {tokenGuard = 0}; // Number of invalid tokens added to circular token buffer to catch references to old tokens
|
||||
#endif
|
||||
// Token lookahead buffer size
|
||||
enum {tokenBufferSize = tokenLookahead + tokenGuard};
|
||||
|
||||
Token tokens[tokenBufferSize]; // Circular buffer of recently read or
|
||||
// lookahead tokens
|
||||
Token *nextToken; // Address of next Token in the
|
||||
// circular buffer to be returned by
|
||||
// get()
|
||||
int nTokensFwd; // Net number of Tokens on which
|
||||
// unget() has been called; these
|
||||
// Tokens are ahead of nextToken
|
||||
Token tokens[tokenBufferSize]; // Circular buffer of recently read or lookahead tokens
|
||||
Token *nextToken; // Address of next Token in the circular buffer to be returned by get()
|
||||
int nTokensFwd; // Net number of Tokens on which unget() has been called; these Tokens are ahead of nextToken
|
||||
#ifdef DEBUG
|
||||
int nTokensBack; // Number of Tokens on which unget()
|
||||
// can be called; these Tokens are
|
||||
// beind nextToken
|
||||
bool savedPreferRegExp[tokenBufferSize]; // Circular buffer of saved
|
||||
// values of preferRegExp to
|
||||
// get() calls
|
||||
int nTokensBack; // Number of Tokens on which unget() can be called; these Tokens are beind nextToken
|
||||
bool savedPreferRegExp[tokenBufferSize]; // Circular buffer of saved values of preferRegExp to get() calls
|
||||
#endif
|
||||
bool lexingUnit; // True if lexing a unit identifier
|
||||
// immediately following a number
|
||||
bool lexingUnit; // True if lexing a unit identifier immediately following a number
|
||||
public:
|
||||
World &world;
|
||||
Reader reader;
|
||||
|
||||
Lexer(World &world, const String &source, const String &sourceLocation,
|
||||
uint32 initialLineNum = 1);
|
||||
|
||||
Lexer(World &world, const String &source, const String &sourceLocation, uint32 initialLineNum = 1);
|
||||
|
||||
const Token &get(bool preferRegExp);
|
||||
const Token *eat(bool preferRegExp, Token::Kind kind);
|
||||
const Token &peek(bool preferRegExp);
|
||||
void redesignate(bool preferRegExp);
|
||||
void unget();
|
||||
uint32 getPos() const;
|
||||
|
||||
|
||||
private:
|
||||
void syntaxError(const char *message, uint backUp = 1);
|
||||
char16 getChar();
|
||||
|
@ -97,7 +80,7 @@ namespace JavaScript
|
|||
char16 peekChar();
|
||||
char16 internalPeekChar(char16 ch);
|
||||
bool testChar(char16 ch);
|
||||
|
||||
|
||||
char16 lexEscape(bool unicodeOnly);
|
||||
bool lexIdentifier(String &s, bool allowLeadingDigit);
|
||||
bool lexNumeral();
|
||||
|
@ -106,20 +89,16 @@ namespace JavaScript
|
|||
void lexToken(bool preferRegExp);
|
||||
};
|
||||
|
||||
|
||||
#ifndef DEBUG
|
||||
inline void Lexer::redesignate(bool) {} // See description for the DEBUG
|
||||
// version inside parser.cpp
|
||||
inline void Lexer::redesignate(bool) {} // See description for the DEBUG version inside lexer.cpp
|
||||
#endif
|
||||
|
||||
// Return the position of the first character of the next token,
|
||||
// which must have been peeked.
|
||||
inline uint32
|
||||
Lexer::getPos() const
|
||||
// Return the position of the first character of the next token, which must have been peeked.
|
||||
inline uint32 Lexer::getPos() const
|
||||
{
|
||||
ASSERT(nTokensFwd);
|
||||
return nextToken->getPos();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif /* lexer_h___ */
|
||||
|
|
|
@ -60,10 +60,6 @@ namespace JavaScript {
|
|||
Identifier(const Token &t) {
|
||||
return new(getArena()) IdentifierExprNode(t);
|
||||
}
|
||||
static IdentifierList *
|
||||
ListedIdentifier(String &name) {
|
||||
return new(getArena()) IdentifierList(*new StringAtom(name));
|
||||
}
|
||||
#if 0
|
||||
static QualifiedIdentifierNode
|
||||
QualifiedIdentifier(Node qualifier, IdentifierNode identifier ) {
|
||||
|
|
5310
js2/src/parser.cpp
5310
js2/src/parser.cpp
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
1646
js2/src/parser.h
1646
js2/src/parser.h
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,84 +1,82 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the JavaScript 2 Prototype.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU Public License (the "GPL"), in which case the
|
||||
* provisions of the GPL are applicable instead of those above.
|
||||
* If you wish to allow use of your version of this file only
|
||||
* under the terms of the GPL and not to allow others to use your
|
||||
* version of this file under the NPL, indicate your decision by
|
||||
* deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this
|
||||
* file under either the NPL or the GPL.
|
||||
*/
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the JavaScript 2 Prototype.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU Public License (the "GPL"), in which case the
|
||||
* provisions of the GPL are applicable instead of those above.
|
||||
* If you wish to allow use of your version of this file only
|
||||
* under the terms of the GPL and not to allow others to use your
|
||||
* version of this file under the NPL, indicate your decision by
|
||||
* deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this
|
||||
* file under either the NPL or the GPL.
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "reader.h"
|
||||
|
||||
namespace JavaScript
|
||||
{
|
||||
namespace JS = JavaScript;
|
||||
|
||||
|
||||
// Create a Reader reading characters from the source string.
|
||||
// sourceLocation describes the origin of the source and may be used for
|
||||
// error messages. initialLineNum is the line number of the first line of the
|
||||
// source string.
|
||||
Reader::Reader(const String &source, const String &sourceLocation,
|
||||
uint32 initialLineNum):
|
||||
source(source + uni::null), sourceLocation(sourceLocation),
|
||||
initialLineNum(initialLineNum)
|
||||
{
|
||||
begin = p = this->source.data();
|
||||
end = begin + this->source.size() - 1;
|
||||
JS::Reader::Reader(const String &source, const String &sourceLocation, uint32 initialLineNum):
|
||||
source(source + uni::null), sourceLocation(sourceLocation), initialLineNum(initialLineNum)
|
||||
{
|
||||
begin = p = this->source.data();
|
||||
end = begin + this->source.size() - 1;
|
||||
#ifdef DEBUG
|
||||
recordString = 0;
|
||||
recordString = 0;
|
||||
#endif
|
||||
beginLine();
|
||||
}
|
||||
beginLine();
|
||||
}
|
||||
|
||||
|
||||
// Mark the beginning of a line. Call this after reading every line break to
|
||||
// fill out the line start table.
|
||||
void
|
||||
Reader::beginLine()
|
||||
{
|
||||
ASSERT(p <= end && (!linePositions.size() || p > linePositions.back()));
|
||||
linePositions.push_back(p);
|
||||
}
|
||||
void JS::Reader::beginLine()
|
||||
{
|
||||
ASSERT(p <= end && (!linePositions.size() || p > linePositions.back()));
|
||||
linePositions.push_back(p);
|
||||
}
|
||||
|
||||
|
||||
// Return the number of the line containing the given character position.
|
||||
// The line starts should have been recorded by calling beginLine.
|
||||
uint32
|
||||
Reader::posToLineNum(uint32 pos) const
|
||||
{
|
||||
ASSERT(pos <= getPos());
|
||||
std::vector<const char16 *>::const_iterator i =
|
||||
std::upper_bound(linePositions.begin(), linePositions.end(),
|
||||
begin + pos);
|
||||
ASSERT(i != linePositions.begin());
|
||||
|
||||
return static_cast<uint32>(i-1 - linePositions.begin()) +
|
||||
initialLineNum;
|
||||
}
|
||||
|
||||
uint32 JS::Reader::posToLineNum(uint32 pos) const
|
||||
{
|
||||
ASSERT(pos <= getPos());
|
||||
std::vector<const char16 *>::const_iterator i =
|
||||
std::upper_bound(linePositions.begin(), linePositions.end(), begin + pos);
|
||||
ASSERT(i != linePositions.begin());
|
||||
|
||||
return static_cast<uint32>(i-1 - linePositions.begin()) +
|
||||
initialLineNum;
|
||||
}
|
||||
|
||||
|
||||
// Return the character position as well as pointers to the beginning and end
|
||||
// (not including the line terminator) of the nth line. If lineNum is out of
|
||||
// range, return 0 and two nulls. The line starts should have been recorded by
|
||||
|
@ -86,131 +84,126 @@ namespace JavaScript
|
|||
// manually finds the line ending by searching for a line break; otherwise,
|
||||
// getLine assumes that the line ends one character before the beginning
|
||||
// of the next line.
|
||||
uint32
|
||||
Reader::getLine(uint32 lineNum, const char16 *&lineBegin,
|
||||
const char16 *&lineEnd) const
|
||||
{
|
||||
lineBegin = 0;
|
||||
lineEnd = 0;
|
||||
if (lineNum < initialLineNum)
|
||||
return 0;
|
||||
lineNum -= initialLineNum;
|
||||
if (lineNum >= linePositions.size())
|
||||
return 0;
|
||||
lineBegin = linePositions[lineNum];
|
||||
|
||||
const char16 *e;
|
||||
++lineNum;
|
||||
if (lineNum < linePositions.size())
|
||||
e = linePositions[lineNum] - 1;
|
||||
else {
|
||||
e = lineBegin;
|
||||
const char16 *end = Reader::end;
|
||||
while (e != end && !isLineBreak(*e))
|
||||
++e;
|
||||
}
|
||||
lineEnd = e;
|
||||
return static_cast<uint32>(lineBegin - begin);
|
||||
uint32 JS::Reader::getLine(uint32 lineNum, const char16 *&lineBegin, const char16 *&lineEnd) const
|
||||
{
|
||||
lineBegin = 0;
|
||||
lineEnd = 0;
|
||||
if (lineNum < initialLineNum)
|
||||
return 0;
|
||||
lineNum -= initialLineNum;
|
||||
if (lineNum >= linePositions.size())
|
||||
return 0;
|
||||
lineBegin = linePositions[lineNum];
|
||||
|
||||
const char16 *e;
|
||||
++lineNum;
|
||||
if (lineNum < linePositions.size())
|
||||
e = linePositions[lineNum] - 1;
|
||||
else {
|
||||
e = lineBegin;
|
||||
const char16 *end = Reader::end;
|
||||
while (e != end && !isLineBreak(*e))
|
||||
++e;
|
||||
}
|
||||
|
||||
lineEnd = e;
|
||||
return static_cast<uint32>(lineBegin - begin);
|
||||
}
|
||||
|
||||
|
||||
// Begin accumulating characters into the recordString, whose initial value is
|
||||
// ignored and cleared. Each character passed to recordChar() is added to the
|
||||
// end of the recordString. Recording ends when endRecord() or beginLine()
|
||||
// is called. Recording is significantly optimized when the characters passed
|
||||
// to readChar() are the same characters as read by get(). In this case the
|
||||
// record String does not get allocated until endRecord() is called or a
|
||||
// recorded String does not get allocated until endRecord() is called or a
|
||||
// discrepancy appears between get() and recordChar().
|
||||
void
|
||||
Reader::beginRecording(String &recordString)
|
||||
{
|
||||
Reader::recordString = &recordString;
|
||||
recordBase = p;
|
||||
recordPos = p;
|
||||
}
|
||||
void JS::Reader::beginRecording(String &recordString)
|
||||
{
|
||||
Reader::recordString = &recordString;
|
||||
recordBase = p;
|
||||
recordPos = p;
|
||||
}
|
||||
|
||||
|
||||
// Append ch to the recordString.
|
||||
void
|
||||
Reader::recordChar(char16 ch)
|
||||
{
|
||||
ASSERT(recordString);
|
||||
if (recordPos) {
|
||||
if (recordPos != end && *recordPos == ch) {
|
||||
recordPos++;
|
||||
return;
|
||||
} else {
|
||||
recordString->assign(recordBase, recordPos);
|
||||
recordPos = 0;
|
||||
}
|
||||
void JS::Reader::recordChar(char16 ch)
|
||||
{
|
||||
ASSERT(recordString);
|
||||
if (recordPos) {
|
||||
if (recordPos != end && *recordPos == ch) {
|
||||
recordPos++;
|
||||
return;
|
||||
} else {
|
||||
recordString->assign(recordBase, recordPos);
|
||||
recordPos = 0;
|
||||
}
|
||||
*recordString += ch;
|
||||
}
|
||||
|
||||
*recordString += ch;
|
||||
}
|
||||
|
||||
|
||||
// Finish recording characters into the recordString that was last passed to
|
||||
// beginRecording(). Return that recordString.
|
||||
String &
|
||||
Reader::endRecording()
|
||||
{
|
||||
String *rs = recordString;
|
||||
ASSERT(rs);
|
||||
if (recordPos)
|
||||
rs->assign(recordBase, recordPos);
|
||||
recordString = 0;
|
||||
return *rs;
|
||||
}
|
||||
JS::String &JS::Reader::endRecording()
|
||||
{
|
||||
String *rs = recordString;
|
||||
ASSERT(rs);
|
||||
if (recordPos)
|
||||
rs->assign(recordBase, recordPos);
|
||||
recordString = 0;
|
||||
return *rs;
|
||||
}
|
||||
|
||||
|
||||
// Report an error at the given character position in the source code.
|
||||
void
|
||||
Reader::error(Exception::Kind kind, const String &message, uint32 pos)
|
||||
{
|
||||
uint32 lineNum = posToLineNum(pos);
|
||||
const char16 *lineBegin;
|
||||
const char16 *lineEnd;
|
||||
uint32 linePos = getLine(lineNum, lineBegin, lineEnd);
|
||||
ASSERT(lineBegin && lineEnd && linePos <= pos);
|
||||
|
||||
throw Exception(kind, message, sourceLocation, lineNum, pos - linePos,
|
||||
pos, lineBegin, lineEnd);
|
||||
}
|
||||
void JS::Reader::error(Exception::Kind kind, const String &message, uint32 pos)
|
||||
{
|
||||
uint32 lineNum = posToLineNum(pos);
|
||||
const char16 *lineBegin;
|
||||
const char16 *lineEnd;
|
||||
uint32 linePos = getLine(lineNum, lineBegin, lineEnd);
|
||||
ASSERT(lineBegin && lineEnd && linePos <= pos);
|
||||
|
||||
throw Exception(kind, message, sourceLocation, lineNum, pos - linePos, pos, lineBegin, lineEnd);
|
||||
}
|
||||
|
||||
|
||||
// Read a line from the input file, including the trailing line break character.
|
||||
// Return the total number of characters read, which is str's length.
|
||||
// Translate <CR> and <CR><LF> sequences to <LF> characters; a <CR><LF> sequence
|
||||
// only counts as one character.
|
||||
size_t
|
||||
LineReader::readLine(string &str)
|
||||
{
|
||||
int ch;
|
||||
bool oldCRWasLast = crWasLast;
|
||||
crWasLast = false;
|
||||
size_t JS::LineReader::readLine(string &str)
|
||||
{
|
||||
int ch;
|
||||
bool oldCRWasLast = crWasLast;
|
||||
crWasLast = false;
|
||||
|
||||
str.resize(0);
|
||||
while ((ch = getc(in)) != EOF) {
|
||||
if (ch == '\n') {
|
||||
if (!str.size() && oldCRWasLast)
|
||||
continue;
|
||||
str += '\n';
|
||||
break;
|
||||
}
|
||||
if (ch == '\r') {
|
||||
crWasLast = true;
|
||||
str += '\n';
|
||||
break;
|
||||
}
|
||||
str += static_cast<char>(ch);
|
||||
str.resize(0);
|
||||
while ((ch = getc(in)) != EOF) {
|
||||
if (ch == '\n') {
|
||||
if (!str.size() && oldCRWasLast)
|
||||
continue;
|
||||
str += '\n';
|
||||
break;
|
||||
}
|
||||
|
||||
return str.size();
|
||||
if (ch == '\r') {
|
||||
crWasLast = true;
|
||||
str += '\n';
|
||||
break;
|
||||
}
|
||||
str += static_cast<char>(ch);
|
||||
}
|
||||
|
||||
|
||||
size_t
|
||||
LineReader::readLine(String &wstr)
|
||||
{
|
||||
string str;
|
||||
size_t n = readLine(str);
|
||||
wstr.resize(n);
|
||||
std::transform(str.begin(), str.end(), wstr.begin(), widen);
|
||||
return n;
|
||||
}
|
||||
|
||||
} /* namespace JavaScript */
|
||||
return str.size();
|
||||
}
|
||||
|
||||
|
||||
// Same as readLine of a string except that widens the resulting characters to Unicode.
|
||||
size_t JS::LineReader::readLine(String &wstr)
|
||||
{
|
||||
string str;
|
||||
size_t n = readLine(str);
|
||||
wstr.resize(n);
|
||||
std::transform(str.begin(), str.end(), wstr.begin(), widen);
|
||||
return n;
|
||||
}
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU Public License (the "GPL"), in which case the
|
||||
|
@ -46,31 +46,25 @@ namespace JavaScript {
|
|||
// Calling get() yields all of the characters in sequence.
|
||||
// One character may be read
|
||||
// past the end of the source; that character appears as a null.
|
||||
|
||||
class Reader {
|
||||
const char16 *begin; // Beginning of source text
|
||||
const char16 *p; // Position in source text
|
||||
const char16 *end; // End of source text; *end is a null character
|
||||
const char16 *begin; // Beginning of source text
|
||||
const char16 *p; // Position in source text
|
||||
const char16 *end; // End of source text; *end is a null character
|
||||
public:
|
||||
const String source; // Source text
|
||||
const String sourceLocation; // Description of location from which
|
||||
// the source text came
|
||||
const String source; // Source text
|
||||
const String sourceLocation; // Description of location from which the source text came
|
||||
private:
|
||||
const uint32 initialLineNum; // One-based number of current line
|
||||
std::vector<const char16 *> linePositions; // Array of line starts
|
||||
// recorded by beginLine()
|
||||
const uint32 initialLineNum; // One-based number of current line
|
||||
std::vector<const char16 *> linePositions; // Array of line starts recorded by beginLine()
|
||||
|
||||
String *recordString; // String, if any, into which recordChar()
|
||||
// records characters; not owned by the Reader
|
||||
const char16 *recordBase; // Position of last beginRecording() call
|
||||
const char16 *recordPos; // Position of last recordChar() call;
|
||||
// nil if a discrepancy occurred
|
||||
public:
|
||||
Reader(const String &source, const String &sourceLocation,
|
||||
uint32 initialLineNum = 1);
|
||||
String *recordString; // String, if any, into which recordChar() records characters; not owned by the Reader
|
||||
const char16 *recordBase; // Position of last beginRecording() call
|
||||
const char16 *recordPos; // Position of last recordChar() call; nil if a discrepancy occurred
|
||||
public:
|
||||
Reader(const String &source, const String &sourceLocation, uint32 initialLineNum = 1);
|
||||
private:
|
||||
Reader(const Reader&); // No copy constructor
|
||||
void operator=(const Reader&);// No assignment operator
|
||||
Reader(const Reader&); // No copy constructor
|
||||
void operator=(const Reader&); // No assignment operator
|
||||
public:
|
||||
|
||||
char16 get() {ASSERT(p <= end);return *p++;}
|
||||
|
@ -78,13 +72,13 @@ namespace JavaScript {
|
|||
void unget(uint32 n = 1) {ASSERT(p >= begin + n); p -= n;}
|
||||
uint32 getPos() const {return static_cast<uint32>(p - begin);}
|
||||
void setPos(uint32 pos) {ASSERT(pos <= getPos()); p = begin + pos;}
|
||||
|
||||
|
||||
bool eof() const {ASSERT(p <= end); return p == end;}
|
||||
bool peekEof(char16 ch) const {
|
||||
// Faster version. ch is the result of a peek
|
||||
ASSERT(p <= end && *p == ch);
|
||||
return !ch && p == end;
|
||||
}
|
||||
}
|
||||
bool pastEof() const {return p == end+1;}
|
||||
bool getEof(char16 ch) const {
|
||||
// Faster version. ch is the result of a get
|
||||
|
@ -92,22 +86,22 @@ namespace JavaScript {
|
|||
}
|
||||
void beginLine();
|
||||
uint32 posToLineNum(uint32 pos) const;
|
||||
uint32 getLine(uint32 lineNum, const char16 *&lineBegin,
|
||||
const char16 *&lineEnd) const;
|
||||
uint32 getLine(uint32 lineNum, const char16 *&lineBegin, const char16 *&lineEnd) const;
|
||||
void beginRecording(String &recordString);
|
||||
void recordChar(char16 ch);
|
||||
String &endRecording();
|
||||
|
||||
|
||||
void error(Exception::Kind kind, const String &message, uint32 pos);
|
||||
};
|
||||
|
||||
|
||||
|
||||
class LineReader {
|
||||
FILE *in; // File from which currently reading
|
||||
bool crWasLast; // True if a CR character was the last one read
|
||||
|
||||
FILE *in; // File from which currently reading
|
||||
bool crWasLast; // True if a CR character was the last one read
|
||||
|
||||
public:
|
||||
explicit LineReader(FILE *in): in(in), crWasLast(false) {}
|
||||
|
||||
|
||||
size_t readLine(string &str);
|
||||
size_t readLine(String &wstr);
|
||||
};
|
||||
|
|
|
@ -1,362 +1,360 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the JavaScript 2 Prototype.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU Public License (the "GPL"), in which case the
|
||||
* provisions of the GPL are applicable instead of those above.
|
||||
* If you wish to allow use of your version of this file only
|
||||
* under the terms of the GPL and not to allow others to use your
|
||||
* version of this file under the NPL, indicate your decision by
|
||||
* deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this
|
||||
* file under either the NPL or the GPL.
|
||||
*/
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the JavaScript 2 Prototype.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU Public License (the "GPL"), in which case the
|
||||
* provisions of the GPL are applicable instead of those above.
|
||||
* If you wish to allow use of your version of this file only
|
||||
* under the terms of the GPL and not to allow others to use your
|
||||
* version of this file under the NPL, indicate your decision by
|
||||
* deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this
|
||||
* file under either the NPL or the GPL.
|
||||
*/
|
||||
|
||||
#include "token.h"
|
||||
#include "formatter.h"
|
||||
#include "world.h"
|
||||
|
||||
namespace JavaScript
|
||||
{
|
||||
|
||||
const char *const Token::kindNames[kindsEnd] = {
|
||||
namespace JS = JavaScript;
|
||||
|
||||
// Special
|
||||
"end of input", // end
|
||||
"number", // number
|
||||
"string", // string
|
||||
"unit", // unit
|
||||
"regular expression", // regExp
|
||||
|
||||
// Punctuators
|
||||
"(", // openParenthesis
|
||||
")", // closeParenthesis
|
||||
"[", // openBracket
|
||||
"]", // closeBracket
|
||||
"{", // openBrace
|
||||
"}", // closeBrace
|
||||
",", // comma
|
||||
";", // semicolon
|
||||
".", // dot
|
||||
"..", // doubleDot
|
||||
"...", // tripleDot
|
||||
"->", // arrow
|
||||
":", // colon
|
||||
"::", // doubleColon
|
||||
"#", // pound
|
||||
"@", // at
|
||||
"++", // increment
|
||||
"--", // decrement
|
||||
"~", // complement
|
||||
"!", // logicalNot
|
||||
"*", // times
|
||||
"/", // divide
|
||||
"%", // modulo
|
||||
"+", // plus
|
||||
"-", // minus
|
||||
"<<", // leftShift
|
||||
">>", // rightShift
|
||||
">>>", // logicalRightShift
|
||||
"&&", // logicalAnd
|
||||
"^^", // logicalXor
|
||||
"||", // logicalOr
|
||||
"&", // bitwiseAnd
|
||||
"^", // bitwiseXor
|
||||
"|", // bitwiseOr
|
||||
"=", // assignment
|
||||
"*=", // timesEquals
|
||||
"/=", // divideEquals
|
||||
"%=", // moduloEquals
|
||||
"+=", // plusEquals
|
||||
"-=", // minusEquals
|
||||
"<<=", // leftShiftEquals
|
||||
">>=", // rightShiftEquals
|
||||
">>>=", // logicalRightShiftEquals
|
||||
"&&=", // logicalAndEquals
|
||||
"^^=", // logicalXorEquals
|
||||
"||=", // logicalOrEquals
|
||||
"&=", // bitwiseAndEquals
|
||||
"^=", // bitwiseXorEquals
|
||||
"|=", // bitwiseOrEquals
|
||||
"==", // equal
|
||||
"!=", // notEqual
|
||||
"<", // lessThan
|
||||
"<=", // lessThanOrEqual
|
||||
">", // greaterThan
|
||||
">=", // greaterThanOrEqual
|
||||
"===", // identical
|
||||
"!==", // notIdentical
|
||||
"?", // question
|
||||
const char *const JS::Token::kindNames[kindsEnd] = {
|
||||
|
||||
// Reserved words
|
||||
"abstract", // Abstract
|
||||
"break", // Break
|
||||
"case", // Case
|
||||
"catch", // Catch
|
||||
"class", // Class
|
||||
"const", // Const
|
||||
"continue", // Continue
|
||||
"debugger", // Debugger
|
||||
"default", // Default
|
||||
"delete", // Delete
|
||||
"do", // Do
|
||||
"else", // Else
|
||||
"enum", // Enum
|
||||
"export", // Export
|
||||
"extends", // Extends
|
||||
"false", // False
|
||||
"final", // Final
|
||||
"finally", // Finally
|
||||
"for", // For
|
||||
"function", // Function
|
||||
"goto", // Goto
|
||||
"if", // If
|
||||
"implements", // Implements
|
||||
"import", // Import
|
||||
"in", // In
|
||||
"instanceof", // Instanceof
|
||||
"interface", // Interface
|
||||
"namespace", // Namespace
|
||||
"native", // Native
|
||||
"new", // New
|
||||
"null", // Null
|
||||
"package", // Package
|
||||
"private", // Private
|
||||
"protected", // Protected
|
||||
"public", // Public
|
||||
"return", // Return
|
||||
"static", // Static
|
||||
"super", // Super
|
||||
"switch", // Switch
|
||||
"synchronized", // Synchronized
|
||||
"this", // This
|
||||
"throw", // Throw
|
||||
"throws", // Throws
|
||||
"transient", // Transient
|
||||
"true", // True
|
||||
"try", // Try
|
||||
"typeof", // Typeof
|
||||
"use", // Use
|
||||
"var", // Var
|
||||
"void", // Void
|
||||
"volatile", // Volatile
|
||||
"while", // While
|
||||
"with", // With
|
||||
// Special
|
||||
"end of input", // end
|
||||
"number", // number
|
||||
"string", // string
|
||||
"unit", // unit
|
||||
"regular expression", // regExp
|
||||
|
||||
// Non-reserved words
|
||||
"eval", // Eval
|
||||
"exclude", // Exclude
|
||||
"get", // Get
|
||||
"include", // Include
|
||||
"set" // Set
|
||||
};
|
||||
// Punctuators
|
||||
"(", // openParenthesis
|
||||
")", // closeParenthesis
|
||||
"[", // openBracket
|
||||
"]", // closeBracket
|
||||
"{", // openBrace
|
||||
"}", // closeBrace
|
||||
",", // comma
|
||||
";", // semicolon
|
||||
".", // dot
|
||||
"..", // doubleDot
|
||||
"...", // tripleDot
|
||||
"->", // arrow
|
||||
":", // colon
|
||||
"::", // doubleColon
|
||||
"#", // pound
|
||||
"@", // at
|
||||
"++", // increment
|
||||
"--", // decrement
|
||||
"~", // complement
|
||||
"!", // logicalNot
|
||||
"*", // times
|
||||
"/", // divide
|
||||
"%", // modulo
|
||||
"+", // plus
|
||||
"-", // minus
|
||||
"<<", // leftShift
|
||||
">>", // rightShift
|
||||
">>>", // logicalRightShift
|
||||
"&&", // logicalAnd
|
||||
"^^", // logicalXor
|
||||
"||", // logicalOr
|
||||
"&", // bitwiseAnd
|
||||
"^", // bitwiseXor
|
||||
"|", // bitwiseOr
|
||||
"=", // assignment
|
||||
"*=", // timesEquals
|
||||
"/=", // divideEquals
|
||||
"%=", // moduloEquals
|
||||
"+=", // plusEquals
|
||||
"-=", // minusEquals
|
||||
"<<=", // leftShiftEquals
|
||||
">>=", // rightShiftEquals
|
||||
">>>=", // logicalRightShiftEquals
|
||||
"&&=", // logicalAndEquals
|
||||
"^^=", // logicalXorEquals
|
||||
"||=", // logicalOrEquals
|
||||
"&=", // bitwiseAndEquals
|
||||
"^=", // bitwiseXorEquals
|
||||
"|=", // bitwiseOrEquals
|
||||
"==", // equal
|
||||
"!=", // notEqual
|
||||
"<", // lessThan
|
||||
"<=", // lessThanOrEqual
|
||||
">", // greaterThan
|
||||
">=", // greaterThanOrEqual
|
||||
"===", // identical
|
||||
"!==", // notIdentical
|
||||
"?", // question
|
||||
|
||||
const uchar followRet = 1<<Token::canFollowReturn;
|
||||
const uchar isAttr = 1<<Token::isAttribute |
|
||||
1<<Token::canFollowAttribute;
|
||||
const uchar followAttr = 1<<Token::canFollowAttribute;
|
||||
const uchar followGet = 1<<Token::canFollowGet;
|
||||
// Reserved words
|
||||
"abstract", // Abstract
|
||||
"as", // As
|
||||
"break", // Break
|
||||
"case", // Case
|
||||
"catch", // Catch
|
||||
"class", // Class
|
||||
"const", // Const
|
||||
"continue", // Continue
|
||||
"debugger", // Debugger
|
||||
"default", // Default
|
||||
"delete", // Delete
|
||||
"do", // Do
|
||||
"else", // Else
|
||||
"enum", // Enum
|
||||
"export", // Export
|
||||
"extends", // Extends
|
||||
"false", // False
|
||||
"final", // Final
|
||||
"finally", // Finally
|
||||
"for", // For
|
||||
"function", // Function
|
||||
"goto", // Goto
|
||||
"if", // If
|
||||
"implements", // Implements
|
||||
"import", // Import
|
||||
"in", // In
|
||||
"instanceof", // Instanceof
|
||||
"interface", // Interface
|
||||
"namespace", // Namespace
|
||||
"native", // Native
|
||||
"new", // New
|
||||
"null", // Null
|
||||
"package", // Package
|
||||
"private", // Private
|
||||
"protected", // Protected
|
||||
"public", // Public
|
||||
"return", // Return
|
||||
"static", // Static
|
||||
"super", // Super
|
||||
"switch", // Switch
|
||||
"synchronized", // Synchronized
|
||||
"this", // This
|
||||
"throw", // Throw
|
||||
"throws", // Throws
|
||||
"transient", // Transient
|
||||
"true", // True
|
||||
"try", // Try
|
||||
"typeof", // Typeof
|
||||
"use", // Use
|
||||
"var", // Var
|
||||
"void", // Void
|
||||
"volatile", // Volatile
|
||||
"while", // While
|
||||
"with", // With
|
||||
|
||||
const uchar Token::kindFlags[kindsEnd] = {
|
||||
|
||||
// Special
|
||||
followRet, // end
|
||||
0, // number
|
||||
0, // string
|
||||
0, // unit
|
||||
0, // regExp
|
||||
|
||||
// Punctuators
|
||||
0, // openParenthesis
|
||||
0, // closeParenthesis
|
||||
0, // openBracket
|
||||
0, // closeBracket
|
||||
followAttr, // openBrace
|
||||
followRet, // closeBrace
|
||||
0, // comma
|
||||
followRet, // semicolon
|
||||
0, // dot
|
||||
0, // doubleDot
|
||||
0, // tripleDot
|
||||
0, // arrow
|
||||
0, // colon
|
||||
0, // doubleColon
|
||||
0, // pound
|
||||
0, // at
|
||||
0, // increment
|
||||
0, // decrement
|
||||
0, // complement
|
||||
0, // logicalNot
|
||||
0, // times
|
||||
0, // divide
|
||||
0, // modulo
|
||||
0, // plus
|
||||
0, // minus
|
||||
0, // leftShift
|
||||
0, // rightShift
|
||||
0, // logicalRightShift
|
||||
0, // logicalAnd
|
||||
0, // logicalXor
|
||||
0, // logicalOr
|
||||
0, // bitwiseAnd
|
||||
0, // bitwiseXor
|
||||
0, // bitwiseOr
|
||||
0, // assignment
|
||||
0, // timesEquals
|
||||
0, // divideEquals
|
||||
0, // moduloEquals
|
||||
0, // plusEquals
|
||||
0, // minusEquals
|
||||
0, // leftShiftEquals
|
||||
0, // rightShiftEquals
|
||||
0, // logicalRightShiftEquals
|
||||
0, // logicalAndEquals
|
||||
0, // logicalXorEquals
|
||||
0, // logicalOrEquals
|
||||
0, // bitwiseAndEquals
|
||||
0, // bitwiseXorEquals
|
||||
0, // bitwiseOrEquals
|
||||
0, // equal
|
||||
0, // notEqual
|
||||
0, // lessThan
|
||||
0, // lessThanOrEqual
|
||||
0, // greaterThan
|
||||
0, // greaterThanOrEqual
|
||||
0, // identical
|
||||
0, // notIdentical
|
||||
0, // question
|
||||
|
||||
// Reserved words
|
||||
followAttr, // Abstract
|
||||
0, // Break
|
||||
0, // Case
|
||||
0, // Catch
|
||||
followAttr, // Class
|
||||
followAttr, // Const
|
||||
0, // Continue
|
||||
0, // Debugger
|
||||
0, // Default
|
||||
0, // Delete
|
||||
0, // Do
|
||||
followRet, // Else
|
||||
0, // Enum
|
||||
followAttr, // Export
|
||||
0, // Extends
|
||||
0, // False
|
||||
isAttr, // Final
|
||||
0, // Finally
|
||||
0, // For
|
||||
followAttr, // Function
|
||||
0, // Goto
|
||||
0, // If
|
||||
0, // Implements
|
||||
0, // Import
|
||||
0, // In
|
||||
0, // Instanceof
|
||||
followAttr, // Interface
|
||||
followAttr, // Namespace
|
||||
followAttr, // Native
|
||||
0, // New
|
||||
0, // Null
|
||||
isAttr, // Package
|
||||
isAttr, // Private
|
||||
followAttr, // Protected
|
||||
isAttr, // Public
|
||||
0, // Return
|
||||
isAttr, // Static
|
||||
0, // Super
|
||||
0, // Switch
|
||||
followAttr, // Synchronized
|
||||
0, // This
|
||||
0, // Throw
|
||||
0, // Throws
|
||||
followAttr, // Transient
|
||||
0, // True
|
||||
0, // Try
|
||||
0, // Typeof
|
||||
0, // Use
|
||||
followAttr, // Var
|
||||
0, // Void
|
||||
isAttr, // Volatile
|
||||
followRet, // While
|
||||
0, // With
|
||||
|
||||
// Non-reserved words
|
||||
isAttr|followGet, // Eval
|
||||
isAttr|followGet, // Exclude
|
||||
isAttr|followGet, // Get
|
||||
isAttr|followGet, // Include
|
||||
isAttr|followGet, // Set
|
||||
|
||||
isAttr|followGet // identifier
|
||||
// Non-reserved words
|
||||
"eval", // Eval
|
||||
"exclude", // Exclude
|
||||
"get", // Get
|
||||
"include", // Include
|
||||
"set" // Set
|
||||
};
|
||||
|
||||
|
||||
static const uchar followRet = 1<<JS::Token::canFollowReturn;
|
||||
static const uchar isAttr = 1<<JS::Token::isAttribute | 1<<JS::Token::canFollowAttribute;
|
||||
static const uchar followAttr = 1<<JS::Token::canFollowAttribute;
|
||||
static const uchar followGet = 1<<JS::Token::canFollowGet;
|
||||
|
||||
const uchar JS::Token::kindFlags[kindsEnd] = {
|
||||
// Special
|
||||
followRet, // end
|
||||
0, // number
|
||||
0, // string
|
||||
0, // unit
|
||||
0, // regExp
|
||||
|
||||
// Punctuators
|
||||
0, // openParenthesis
|
||||
0, // closeParenthesis
|
||||
0, // openBracket
|
||||
0, // closeBracket
|
||||
followAttr, // openBrace
|
||||
followRet, // closeBrace
|
||||
0, // comma
|
||||
followRet, // semicolon
|
||||
0, // dot
|
||||
0, // doubleDot
|
||||
0, // tripleDot
|
||||
0, // arrow
|
||||
0, // colon
|
||||
0, // doubleColon
|
||||
0, // pound
|
||||
0, // at
|
||||
0, // increment
|
||||
0, // decrement
|
||||
0, // complement
|
||||
0, // logicalNot
|
||||
0, // times
|
||||
0, // divide
|
||||
0, // modulo
|
||||
0, // plus
|
||||
0, // minus
|
||||
0, // leftShift
|
||||
0, // rightShift
|
||||
0, // logicalRightShift
|
||||
0, // logicalAnd
|
||||
0, // logicalXor
|
||||
0, // logicalOr
|
||||
0, // bitwiseAnd
|
||||
0, // bitwiseXor
|
||||
0, // bitwiseOr
|
||||
0, // assignment
|
||||
0, // timesEquals
|
||||
0, // divideEquals
|
||||
0, // moduloEquals
|
||||
0, // plusEquals
|
||||
0, // minusEquals
|
||||
0, // leftShiftEquals
|
||||
0, // rightShiftEquals
|
||||
0, // logicalRightShiftEquals
|
||||
0, // logicalAndEquals
|
||||
0, // logicalXorEquals
|
||||
0, // logicalOrEquals
|
||||
0, // bitwiseAndEquals
|
||||
0, // bitwiseXorEquals
|
||||
0, // bitwiseOrEquals
|
||||
0, // equal
|
||||
0, // notEqual
|
||||
0, // lessThan
|
||||
0, // lessThanOrEqual
|
||||
0, // greaterThan
|
||||
0, // greaterThanOrEqual
|
||||
0, // identical
|
||||
0, // notIdentical
|
||||
0, // question
|
||||
|
||||
// Reserved words
|
||||
isAttr, // Abstract
|
||||
0, // As
|
||||
0, // Break
|
||||
0, // Case
|
||||
0, // Catch
|
||||
followAttr, // Class
|
||||
followAttr, // Const
|
||||
0, // Continue
|
||||
0, // Debugger
|
||||
0, // Default
|
||||
0, // Delete
|
||||
0, // Do
|
||||
followRet, // Else
|
||||
0, // Enum
|
||||
followAttr, // Export
|
||||
0, // Extends
|
||||
isAttr, // False
|
||||
isAttr, // Final
|
||||
0, // Finally
|
||||
0, // For
|
||||
followAttr, // Function
|
||||
0, // Goto
|
||||
0, // If
|
||||
0, // Implements
|
||||
0, // Import
|
||||
0, // In
|
||||
0, // Instanceof
|
||||
followAttr, // Interface
|
||||
followAttr, // Namespace
|
||||
followAttr, // Native
|
||||
0, // New
|
||||
0, // Null
|
||||
isAttr, // Package
|
||||
isAttr, // Private
|
||||
followAttr, // Protected
|
||||
isAttr, // Public
|
||||
0, // Return
|
||||
isAttr, // Static
|
||||
0, // Super
|
||||
0, // Switch
|
||||
followAttr, // Synchronized
|
||||
0, // This
|
||||
0, // Throw
|
||||
0, // Throws
|
||||
followAttr, // Transient
|
||||
isAttr, // True
|
||||
0, // Try
|
||||
0, // Typeof
|
||||
0, // Use
|
||||
followAttr, // Var
|
||||
0, // Void
|
||||
isAttr, // Volatile
|
||||
followRet, // While
|
||||
0, // With
|
||||
|
||||
// Non-reserved words
|
||||
isAttr|followGet, // Eval
|
||||
isAttr|followGet, // Exclude
|
||||
isAttr|followGet, // Get
|
||||
isAttr|followGet, // Include
|
||||
isAttr|followGet, // Set
|
||||
|
||||
isAttr|followGet // identifier
|
||||
};
|
||||
|
||||
|
||||
// Initialize the keywords in the given world.
|
||||
void
|
||||
Token::initKeywords(World &world)
|
||||
{
|
||||
const char *const*keywordName = kindNames + keywordsBegin;
|
||||
for (Kind kind = keywordsBegin; kind != keywordsEnd;
|
||||
kind = Kind(kind+1))
|
||||
world.identifiers[widenCString(*keywordName++)].tokenKind = kind;
|
||||
}
|
||||
void JS::Token::initKeywords(World &world)
|
||||
{
|
||||
const char *const*keywordName = kindNames + keywordsBegin;
|
||||
for (Kind kind = keywordsBegin; kind != keywordsEnd;
|
||||
kind = Kind(kind+1))
|
||||
world.identifiers[widenCString(*keywordName++)].tokenKind = kind;
|
||||
}
|
||||
|
||||
|
||||
// Print a description of the token to f.
|
||||
void
|
||||
Token::print(Formatter &f, bool debug) const
|
||||
{
|
||||
switch (getKind()) {
|
||||
case end:
|
||||
f << "[end]";
|
||||
break;
|
||||
|
||||
case number:
|
||||
if (debug)
|
||||
f << "[number " << /* getValue() << */ ']';
|
||||
f << getChars();
|
||||
break;
|
||||
|
||||
case unit:
|
||||
if (debug)
|
||||
f << "[unit]";
|
||||
/* no break */
|
||||
case string:
|
||||
quoteString(f, getChars(), '"');
|
||||
break;
|
||||
|
||||
case regExp:
|
||||
f << '/' << getIdentifier() << '/' << getChars();
|
||||
break;
|
||||
|
||||
case identifier:
|
||||
if (debug)
|
||||
f << "[identifier]";
|
||||
f << getIdentifier();
|
||||
break;
|
||||
|
||||
default:
|
||||
f << getKind();
|
||||
}
|
||||
}
|
||||
void JS::Token::print(Formatter &f, bool debug) const
|
||||
{
|
||||
switch (getKind()) {
|
||||
case end:
|
||||
f << "[end]";
|
||||
break;
|
||||
|
||||
case number:
|
||||
if (debug)
|
||||
f << "[number " << /* getValue() << */ ']';
|
||||
f << getChars();
|
||||
break;
|
||||
|
||||
case unit:
|
||||
if (debug)
|
||||
f << "[unit]";
|
||||
/* no break */
|
||||
case string:
|
||||
quoteString(f, getChars(), '"');
|
||||
break;
|
||||
|
||||
case regExp:
|
||||
f << '/' << getIdentifier() << '/' << getChars();
|
||||
break;
|
||||
|
||||
case identifier:
|
||||
if (debug)
|
||||
f << "[identifier]";
|
||||
f << getIdentifier();
|
||||
break;
|
||||
|
||||
default:
|
||||
f << getKind();
|
||||
}
|
||||
}
|
||||
|
|
370
js2/src/token.h
370
js2/src/token.h
|
@ -17,7 +17,7 @@
|
|||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU Public License (the "GPL"), in which case the
|
||||
|
@ -39,177 +39,163 @@
|
|||
#include "strings.h"
|
||||
#include "formatter.h"
|
||||
|
||||
namespace JavaScript
|
||||
namespace JavaScript
|
||||
{
|
||||
class StringAtom;
|
||||
class World;
|
||||
|
||||
|
||||
class Token {
|
||||
public:
|
||||
enum Kind {
|
||||
// Keep synchronized with kindNames, kindFlags, and
|
||||
// tokenBinaryOperatorInfos tables
|
||||
// Keep synchronized with kindNames, kindFlags, and tokenBinaryOperatorInfos tables
|
||||
|
||||
// Special
|
||||
end, // End of token stream
|
||||
number, // Number
|
||||
string, // String
|
||||
unit, // Unit after number
|
||||
regExp, // Regular expression
|
||||
end, // End of token stream
|
||||
number, // Number
|
||||
string, // String
|
||||
unit, // Unit after number
|
||||
regExp, // Regular expression
|
||||
|
||||
// Punctuators
|
||||
openParenthesis, // (
|
||||
closeParenthesis, // )
|
||||
openBracket, // [
|
||||
closeBracket, // ]
|
||||
openBrace, // {
|
||||
closeBrace, // }
|
||||
comma, // ,
|
||||
semicolon, // ;
|
||||
dot, // .
|
||||
doubleDot, // ..
|
||||
tripleDot, // ...
|
||||
arrow, // ->
|
||||
colon, // :
|
||||
doubleColon, // ::
|
||||
pound, // #
|
||||
at, // @
|
||||
|
||||
increment, // ++
|
||||
decrement, // --
|
||||
|
||||
complement, // ~
|
||||
logicalNot, // !
|
||||
|
||||
times, // *
|
||||
divide, // /
|
||||
modulo, // %
|
||||
plus, // +
|
||||
minus, // -
|
||||
leftShift, // <<
|
||||
rightShift, // >>
|
||||
logicalRightShift, // >>>
|
||||
logicalAnd, // &&
|
||||
logicalXor, // ^^
|
||||
logicalOr, // ||
|
||||
bitwiseAnd, // &
|
||||
|
||||
// These must be at constant offsets from logicalAnd ... logicalOr
|
||||
bitwiseXor, // ^
|
||||
bitwiseOr, // |
|
||||
|
||||
assignment, // =
|
||||
openParenthesis, // (
|
||||
closeParenthesis, // )
|
||||
openBracket, // [
|
||||
closeBracket, // ]
|
||||
openBrace, // {
|
||||
closeBrace, // }
|
||||
comma, // ,
|
||||
semicolon, // ;
|
||||
dot, // .
|
||||
doubleDot, // ..
|
||||
tripleDot, // ...
|
||||
arrow, // ->
|
||||
colon, // :
|
||||
doubleColon, // ::
|
||||
pound, // #
|
||||
at, // @
|
||||
|
||||
// These must be at constant offsets from times ... bitwiseOr
|
||||
timesEquals, // *=
|
||||
divideEquals, // /=
|
||||
moduloEquals, // %=
|
||||
plusEquals, // +=
|
||||
minusEquals, // -=
|
||||
leftShiftEquals, // <<=
|
||||
rightShiftEquals, // >>=
|
||||
logicalRightShiftEquals, // >>>=
|
||||
logicalAndEquals, // &&=
|
||||
logicalXorEquals, // ^^=
|
||||
logicalOrEquals, // ||=
|
||||
bitwiseAndEquals, // &=
|
||||
bitwiseXorEquals, // ^=
|
||||
bitwiseOrEquals, // |=
|
||||
|
||||
equal, // ==
|
||||
notEqual, // !=
|
||||
lessThan, // <
|
||||
lessThanOrEqual, // <=
|
||||
greaterThan, // >
|
||||
|
||||
// >, >= must be at constant offsets from <, <=
|
||||
greaterThanOrEqual, // >=
|
||||
identical, // ===
|
||||
notIdentical, // !==
|
||||
|
||||
question, // ?
|
||||
increment, // ++
|
||||
decrement, // --
|
||||
|
||||
complement, // ~
|
||||
logicalNot, // !
|
||||
|
||||
times, // *
|
||||
divide, // /
|
||||
modulo, // %
|
||||
plus, // +
|
||||
minus, // -
|
||||
leftShift, // <<
|
||||
rightShift, // >>
|
||||
logicalRightShift, // >>>
|
||||
logicalAnd, // &&
|
||||
logicalXor, // ^^
|
||||
logicalOr, // ||
|
||||
bitwiseAnd, // & These must be at constant offsets from logicalAnd ... logicalOr
|
||||
bitwiseXor, // ^
|
||||
bitwiseOr, // |
|
||||
|
||||
assignment, // =
|
||||
timesEquals, // *= These must be at constant offsets from times ... bitwiseOr
|
||||
divideEquals, // /=
|
||||
moduloEquals, // %=
|
||||
plusEquals, // +=
|
||||
minusEquals, // -=
|
||||
leftShiftEquals, // <<=
|
||||
rightShiftEquals, // >>=
|
||||
logicalRightShiftEquals, // >>>=
|
||||
logicalAndEquals, // &&=
|
||||
logicalXorEquals, // ^^=
|
||||
logicalOrEquals, // ||=
|
||||
bitwiseAndEquals, // &=
|
||||
bitwiseXorEquals, // ^=
|
||||
bitwiseOrEquals, // |=
|
||||
|
||||
equal, // ==
|
||||
notEqual, // !=
|
||||
lessThan, // <
|
||||
lessThanOrEqual, // <=
|
||||
greaterThan, // > >, >= must be at constant offsets from <, <=
|
||||
greaterThanOrEqual, // >=
|
||||
identical, // ===
|
||||
notIdentical, // !==
|
||||
|
||||
question, // ?
|
||||
|
||||
// Reserved words
|
||||
Abstract, // abstract
|
||||
Break, // break
|
||||
Case, // case
|
||||
Catch, // catch
|
||||
Class, // class
|
||||
Const, // const
|
||||
Continue, // continue
|
||||
Debugger, // debugger
|
||||
Default, // default
|
||||
Delete, // delete
|
||||
Do, // do
|
||||
Else, // else
|
||||
Enum, // enum
|
||||
Export, // export
|
||||
Extends, // extends
|
||||
False, // false
|
||||
Final, // final
|
||||
Finally, // finally
|
||||
For, // for
|
||||
Function, // function
|
||||
Goto, // goto
|
||||
If, // if
|
||||
Implements, // implements
|
||||
Import, // import
|
||||
In, // in
|
||||
Instanceof, // instanceof
|
||||
Interface, // interface
|
||||
Namespace, // namespace
|
||||
Native, // native
|
||||
New, // new
|
||||
Null, // null
|
||||
Package, // package
|
||||
Private, // private
|
||||
Protected, // protected
|
||||
Public, // public
|
||||
Return, // return
|
||||
Static, // static
|
||||
Super, // super
|
||||
Switch, // switch
|
||||
Synchronized, // synchronized
|
||||
This, // this
|
||||
Throw, // throw
|
||||
Throws, // throws
|
||||
Transient, // transient
|
||||
True, // true
|
||||
Try, // try
|
||||
Typeof, // typeof
|
||||
Use, // use
|
||||
Var, // var
|
||||
Void, // void
|
||||
Volatile, // volatile
|
||||
While, // while
|
||||
With, // with
|
||||
Abstract, // abstract
|
||||
As, // as
|
||||
Break, // break
|
||||
Case, // case
|
||||
Catch, // catch
|
||||
Class, // class
|
||||
Const, // const
|
||||
Continue, // continue
|
||||
Debugger, // debugger
|
||||
Default, // default
|
||||
Delete, // delete
|
||||
Do, // do
|
||||
Else, // else
|
||||
Enum, // enum
|
||||
Export, // export
|
||||
Extends, // extends
|
||||
False, // false
|
||||
Final, // final
|
||||
Finally, // finally
|
||||
For, // for
|
||||
Function, // function
|
||||
Goto, // goto
|
||||
If, // if
|
||||
Implements, // implements
|
||||
Import, // import
|
||||
In, // in
|
||||
Instanceof, // instanceof
|
||||
Interface, // interface
|
||||
Namespace, // namespace
|
||||
Native, // native
|
||||
New, // new
|
||||
Null, // null
|
||||
Package, // package
|
||||
Private, // private
|
||||
Protected, // protected
|
||||
Public, // public
|
||||
Return, // return
|
||||
Static, // static
|
||||
Super, // super
|
||||
Switch, // switch
|
||||
Synchronized, // synchronized
|
||||
This, // this
|
||||
Throw, // throw
|
||||
Throws, // throws
|
||||
Transient, // transient
|
||||
True, // true
|
||||
Try, // try
|
||||
Typeof, // typeof
|
||||
Use, // use
|
||||
Var, // var
|
||||
Void, // void
|
||||
Volatile, // volatile
|
||||
While, // while
|
||||
With, // with
|
||||
|
||||
// Non-reserved words
|
||||
Eval, // eval
|
||||
Exclude, // exclude
|
||||
Get, // get
|
||||
Include, // include
|
||||
Set, // set
|
||||
|
||||
identifier, // Non-keyword identifier
|
||||
// (may be same as a keyword if it
|
||||
// contains an escape code)
|
||||
kindsEnd, // End of token kinds
|
||||
|
||||
keywordsBegin = Abstract, // Beginning of range of special
|
||||
// identifier tokens
|
||||
keywordsEnd = identifier, // End of range of special identifier
|
||||
// tokens
|
||||
nonreservedBegin = Eval, // Beginning of range of non-reserved
|
||||
// words
|
||||
Eval, // eval
|
||||
Exclude, // exclude
|
||||
Get, // get
|
||||
Include, // include
|
||||
Set, // set
|
||||
|
||||
identifier, // Non-keyword identifier (may be same as a keyword if it contains an escape code)
|
||||
kindsEnd, // End of token kinds
|
||||
|
||||
keywordsBegin = Abstract, // Beginning of range of special identifier tokens
|
||||
keywordsEnd = identifier, // End of range of special identifier tokens
|
||||
nonreservedBegin = Eval, // Beginning of range of non-reserved words
|
||||
nonreservedEnd = identifier, // End of range of non-reserved words
|
||||
kindsWithCharsBegin = number, // Beginning of range of tokens for
|
||||
// which the chars field (below) is
|
||||
// valid
|
||||
kindsWithCharsEnd = regExp+1 // End of range of tokens for which
|
||||
// the chars field (below) is valid
|
||||
kindsWithCharsBegin = number, // Beginning of range of tokens for which the chars field (below) is valid
|
||||
kindsWithCharsEnd = regExp+1 // End of range of tokens for which the chars field (below) is valid
|
||||
};
|
||||
|
||||
|
||||
#define CASE_TOKEN_ATTRIBUTE_IDENTIFIER \
|
||||
Token::Eval: \
|
||||
case Token::Exclude: \
|
||||
|
@ -227,13 +213,10 @@ namespace JavaScript
|
|||
case Token::identifier
|
||||
|
||||
enum Flag {
|
||||
isAttribute, // True if this token is an attribute
|
||||
canFollowAttribute, // True if this token is an attribute or can
|
||||
// follow an attribute
|
||||
canFollowReturn, // True if this token can follow a return
|
||||
// without an expression
|
||||
canFollowGet // True if this token can follow a get or
|
||||
// set in a FunctionName
|
||||
isAttribute, // True if this token is an attribute
|
||||
canFollowAttribute, // True if this token is an attribute or can follow an attribute
|
||||
canFollowReturn, // True if this token can follow a return without an expression
|
||||
canFollowGet // True if this token can follow a get or set in a FunctionName
|
||||
};
|
||||
|
||||
private:
|
||||
|
@ -241,65 +224,38 @@ namespace JavaScript
|
|||
static const uchar kindFlags[kindsEnd];
|
||||
|
||||
#ifdef DEBUG
|
||||
bool valid; // True if this token has been initialized
|
||||
bool valid; // True if this token has been initialized
|
||||
#endif
|
||||
Kind kind; // The token's kind
|
||||
bool lineBreak; // True if line break precedes this token
|
||||
uint32 pos; // Source position of this token
|
||||
const StringAtom *id; // The token's characters; non-nil for
|
||||
// identifiers, keywords, and regular
|
||||
// expressions only
|
||||
String chars; // The token's characters; valid for strings, units,
|
||||
// numbers, and regular expression flags only
|
||||
float64 value; // The token's value (numbers only)
|
||||
|
||||
Kind kind; // The token's kind
|
||||
bool lineBreak; // True if line break precedes this token
|
||||
uint32 pos; // Source position of this token
|
||||
const StringAtom *id; // The token's characters; non-nil for identifiers, keywords, and regular expressions only
|
||||
String chars; // The token's characters; valid for strings, units, numbers, and regular expression flags only
|
||||
float64 value; // The token's value (numbers only)
|
||||
|
||||
#ifdef DEBUG
|
||||
Token(): valid(false) {}
|
||||
#endif
|
||||
|
||||
public:
|
||||
static void initKeywords(World &world);
|
||||
static bool isSpecialKind(Kind kind) {
|
||||
return kind <= regExp || kind == identifier;
|
||||
}
|
||||
static const char *kindName(Kind kind) {
|
||||
ASSERT(uint(kind) < kindsEnd);
|
||||
return kindNames[kind];
|
||||
}
|
||||
static bool isSpecialKind(Kind kind) {return kind <= regExp || kind == identifier;}
|
||||
static const char *kindName(Kind kind) {ASSERT(uint(kind) < kindsEnd); return kindNames[kind];}
|
||||
Kind getKind() const {ASSERT(valid); return kind;}
|
||||
bool hasKind(Kind k) const {ASSERT(valid); return kind == k;}
|
||||
bool hasIdentifierKind() const {
|
||||
ASSERT(nonreservedEnd == identifier && kindsEnd == identifier+1);
|
||||
return kind >= nonreservedBegin;
|
||||
}
|
||||
bool getFlag(Flag f) const {
|
||||
ASSERT(valid);
|
||||
return (kindFlags[kind] & 1<<f) != 0;
|
||||
}
|
||||
bool hasIdentifierKind() const {ASSERT(nonreservedEnd == identifier && kindsEnd == identifier+1); return kind >= nonreservedBegin;}
|
||||
bool getFlag(Flag f) const {ASSERT(valid); return (kindFlags[kind] & 1<<f) != 0;}
|
||||
bool getLineBreak() const {ASSERT(valid); return lineBreak;}
|
||||
uint32 getPos() const {ASSERT(valid); return pos;}
|
||||
const StringAtom &getIdentifier() const {
|
||||
ASSERT(valid && id);
|
||||
return *id;
|
||||
}
|
||||
const String &getChars() const {
|
||||
ASSERT(valid && kind >= kindsWithCharsBegin &&
|
||||
kind < kindsWithCharsEnd);
|
||||
return chars;
|
||||
}
|
||||
float64 getValue() const {
|
||||
ASSERT(valid && kind == number);
|
||||
return value;
|
||||
}
|
||||
friend Formatter &operator<<(Formatter &f, Kind k) {
|
||||
f << kindName(k);
|
||||
return f;
|
||||
}
|
||||
const StringAtom &getIdentifier() const {ASSERT(valid && id); return *id;}
|
||||
const String &getChars() const {ASSERT(valid && kind >= kindsWithCharsBegin && kind < kindsWithCharsEnd); return chars;}
|
||||
float64 getValue() const {ASSERT(valid && kind == number); return value;}
|
||||
friend Formatter &operator<<(Formatter &f, Kind k) {f << kindName(k); return f;}
|
||||
void print(Formatter &f, bool debug = false) const;
|
||||
|
||||
|
||||
friend class Lexer;
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif /* token_h___ */
|
||||
|
|
|
@ -1,35 +1,35 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the JavaScript 2 Prototype.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU Public License (the "GPL"), in which case the
|
||||
* provisions of the GPL are applicable instead of those above.
|
||||
* If you wish to allow use of your version of this file only
|
||||
* under the terms of the GPL and not to allow others to use your
|
||||
* version of this file under the NPL, indicate your decision by
|
||||
* deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this
|
||||
* file under either the NPL or the GPL.
|
||||
*/
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express oqr
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the JavaScript 2 Prototype.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the
|
||||
* terms of the GNU Public License (the "GPL"), in which case the
|
||||
* provisions of the GPL are applicable instead of those above.
|
||||
* If you wish to allow use of your version of this file only
|
||||
* under the terms of the GPL and not to allow others to use your
|
||||
* version of this file under the NPL, indicate your decision by
|
||||
* deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this
|
||||
* file under either the NPL or the GPL.
|
||||
*/
|
||||
|
||||
#include "utilities.h"
|
||||
#ifdef DEBUG
|
||||
|
@ -44,9 +44,9 @@
|
|||
# endif
|
||||
#endif
|
||||
|
||||
namespace JavaScript
|
||||
{
|
||||
|
||||
namespace JS = JavaScript;
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifdef XP_MAC
|
||||
// PStrFromCStr converts the source C string to a destination
|
||||
|
@ -54,112 +54,103 @@ namespace JavaScript
|
|||
// be truncated to fit into an Str255 if necessary.
|
||||
// If the C String pointer is NULL, the pascal string's length is
|
||||
// set to zero.
|
||||
static void
|
||||
PStrFromCStr(const char* src, Str255 &dst)
|
||||
{
|
||||
int length = 0;
|
||||
|
||||
if (src)
|
||||
{
|
||||
char *p = reinterpret_cast<char *>(&dst[1]);
|
||||
int spaceLeft = 255;
|
||||
char ch;
|
||||
while ((ch = *src++) != 0) {
|
||||
*p++ = ch;
|
||||
if (--spaceLeft == 0)
|
||||
break;
|
||||
}
|
||||
length = 255 - spaceLeft;
|
||||
}
|
||||
dst[0] = (uchar)length;
|
||||
}
|
||||
|
||||
static void
|
||||
jsdebugstr(const char *debuggerMsg)
|
||||
{
|
||||
Str255 pStr;
|
||||
|
||||
PStrFromCStr(debuggerMsg, pStr);
|
||||
DebugStr(pStr);
|
||||
}
|
||||
|
||||
static void
|
||||
dprintf(const char *format, ...)
|
||||
{
|
||||
std::va_list ap;
|
||||
char buffer[4096];
|
||||
|
||||
va_start(ap, format);
|
||||
std::vsprintf(buffer, format, ap);
|
||||
va_end(ap);
|
||||
|
||||
jsdebugstr(buffer);
|
||||
}
|
||||
#endif /* XP_MAC */
|
||||
|
||||
|
||||
void
|
||||
Assert(const char *s, const char *file, int line)
|
||||
{
|
||||
static void PStrFromCStr(const char* src, Str255 &dst)
|
||||
{
|
||||
int length = 0;
|
||||
|
||||
if (src)
|
||||
{
|
||||
char *p = reinterpret_cast<char *>(&dst[1]);
|
||||
int spaceLeft = 255;
|
||||
char ch;
|
||||
while ((ch = *src++) != 0) {
|
||||
*p++ = ch;
|
||||
if (--spaceLeft == 0)
|
||||
break;
|
||||
}
|
||||
length = 255 - spaceLeft;
|
||||
}
|
||||
dst[0] = (uchar)length;
|
||||
}
|
||||
|
||||
static void jsdebugstr(const char *debuggerMsg)
|
||||
{
|
||||
Str255 pStr;
|
||||
|
||||
PStrFromCStr(debuggerMsg, pStr);
|
||||
DebugStr(pStr);
|
||||
}
|
||||
|
||||
static void dprintf(const char *format, ...)
|
||||
{
|
||||
std::va_list ap;
|
||||
char buffer[4096];
|
||||
|
||||
va_start(ap, format);
|
||||
std::vsprintf(buffer, format, ap);
|
||||
va_end(ap);
|
||||
|
||||
jsdebugstr(buffer);
|
||||
}
|
||||
#endif /* XP_MAC */
|
||||
|
||||
|
||||
void JS::Assert(const char *s, const char *file, int line)
|
||||
{
|
||||
#if defined(XP_UNIX) || defined(XP_OS2)
|
||||
fprintf(std::stderr, "Assertion failure: %s, at %s:%d\n", s, file, line);
|
||||
fprintf(std::stderr, "Assertion failure: %s, at %s:%d\n", s, file, line);
|
||||
#endif
|
||||
#ifdef XP_MAC
|
||||
dprintf("Assertion failure: %s, at %s:%d\n", s, file, line);
|
||||
dprintf("Assertion failure: %s, at %s:%d\n", s, file, line);
|
||||
#endif
|
||||
#ifdef WIN32
|
||||
DebugBreak();
|
||||
DebugBreak();
|
||||
#endif
|
||||
#ifndef XP_MAC
|
||||
abort();
|
||||
abort();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
||||
|
||||
// Return lg2 of the least power of 2 greater than or equal to n.
|
||||
// Return 0 if n is 0 or 1.
|
||||
uint
|
||||
ceilingLog2(uint32 n)
|
||||
{
|
||||
uint log2 = 0;
|
||||
|
||||
if (n & (n-1))
|
||||
log2++;
|
||||
if (n >> 16)
|
||||
log2 += 16, n >>= 16;
|
||||
if (n >> 8)
|
||||
log2 += 8, n >>= 8;
|
||||
if (n >> 4)
|
||||
log2 += 4, n >>= 4;
|
||||
if (n >> 2)
|
||||
log2 += 2, n >>= 2;
|
||||
if (n >> 1)
|
||||
log2++;
|
||||
return log2;
|
||||
}
|
||||
|
||||
uint JS::ceilingLog2(uint32 n)
|
||||
{
|
||||
uint log2 = 0;
|
||||
|
||||
if (n & (n-1))
|
||||
log2++;
|
||||
if (n >> 16)
|
||||
log2 += 16, n >>= 16;
|
||||
if (n >> 8)
|
||||
log2 += 8, n >>= 8;
|
||||
if (n >> 4)
|
||||
log2 += 4, n >>= 4;
|
||||
if (n >> 2)
|
||||
log2 += 2, n >>= 2;
|
||||
if (n >> 1)
|
||||
log2++;
|
||||
return log2;
|
||||
}
|
||||
|
||||
|
||||
// Return lg2 of the greatest power of 2 less than or equal to n.
|
||||
// This really just finds the highest set bit in the word.
|
||||
// Return 0 if n is 0 or 1.
|
||||
uint
|
||||
floorLog2(uint32 n)
|
||||
{
|
||||
uint log2 = 0;
|
||||
|
||||
if (n >> 16)
|
||||
log2 += 16, n >>= 16;
|
||||
if (n >> 8)
|
||||
log2 += 8, n >>= 8;
|
||||
if (n >> 4)
|
||||
log2 += 4, n >>= 4;
|
||||
if (n >> 2)
|
||||
log2 += 2, n >>= 2;
|
||||
if (n >> 1)
|
||||
log2++;
|
||||
return log2;
|
||||
}
|
||||
|
||||
uint JS::floorLog2(uint32 n)
|
||||
{
|
||||
uint log2 = 0;
|
||||
|
||||
if (n >> 16)
|
||||
log2 += 16, n >>= 16;
|
||||
if (n >> 8)
|
||||
log2 += 8, n >>= 8;
|
||||
if (n >> 4)
|
||||
log2 += 4, n >>= 4;
|
||||
if (n >> 2)
|
||||
log2 += 2, n >>= 2;
|
||||
if (n >> 1)
|
||||
log2++;
|
||||
return log2;
|
||||
}
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#define utilities_h___
|
||||
|
||||
#ifdef MSC_VER
|
||||
// diasble long identifier warnings
|
||||
// disable long identifier warnings
|
||||
# pragma warning(disable: 4786)
|
||||
#endif
|
||||
|
||||
|
@ -62,17 +62,15 @@ namespace JavaScript
|
|||
# define DEBUG_ONLY(_stmt)
|
||||
#endif
|
||||
|
||||
|
||||
//
|
||||
// Random Crap
|
||||
// Mathematics
|
||||
//
|
||||
//
|
||||
|
||||
|
||||
template<class N> N min(N v1, N v2) {return v1 <= v2 ? v1 : v2;}
|
||||
template<class N> N max(N v1, N v2) {return v1 >= v2 ? v1 : v2;}
|
||||
|
||||
uint ceilingLog2(uint32 n);
|
||||
uint floorLog2(uint32 n);
|
||||
|
||||
}
|
||||
|
||||
#endif /* utilities_h___ */
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
#include "hash.h"
|
||||
|
||||
namespace JavaScript {
|
||||
|
||||
|
||||
//
|
||||
// String atom management
|
||||
//
|
||||
|
@ -48,24 +48,19 @@ namespace JavaScript {
|
|||
// StringAtoms A and B have the same character sequences if and only if A and
|
||||
// B are the same StringAtom.
|
||||
|
||||
class StringAtom : public String {
|
||||
class StringAtom: public String {
|
||||
public:
|
||||
// Token::Kind if this is a keyword; Token::identifier if not
|
||||
Token::Kind tokenKind;
|
||||
|
||||
explicit StringAtom(const String &s) :
|
||||
String(s), tokenKind(Token::identifier) {}
|
||||
explicit StringAtom(const String &s): String(s), tokenKind(Token::identifier) {}
|
||||
private:
|
||||
StringAtom(const StringAtom&); // No copy constructor
|
||||
void operator=(const StringAtom&); // No assignment operator
|
||||
};
|
||||
|
||||
inline bool operator==(const StringAtom &s1, const StringAtom &s2) {
|
||||
return &s1 == &s2;
|
||||
}
|
||||
inline bool operator!=(const StringAtom &s1, const StringAtom &s2) {
|
||||
return &s1 != &s2;
|
||||
}
|
||||
inline bool operator==(const StringAtom &s1, const StringAtom &s2) {return &s1 == &s2;}
|
||||
inline bool operator!=(const StringAtom &s1, const StringAtom &s2) {return &s1 != &s2;}
|
||||
|
||||
class StringAtomTable {
|
||||
typedef HashTable<StringAtom, const String&> HT;
|
||||
|
@ -73,10 +68,7 @@ namespace JavaScript {
|
|||
|
||||
public:
|
||||
StringAtom &operator[](const String &s);
|
||||
|
||||
StringAtom &operator[](const char *s) {
|
||||
return operator[](widenCString(s));
|
||||
}
|
||||
StringAtom &operator[](const char *s) {return operator[](widenCString(s));}
|
||||
};
|
||||
|
||||
class World {
|
||||
|
|
Загрузка…
Ссылка в новой задаче