28 #include "interpreter.h"
29 #include "operations.h"
32 #include "regexp_object.h"
33 #include "error_object.h"
42 const ClassInfo RegExpPrototypeImp::info = {
"RegExp", 0, 0, 0};
44 RegExpPrototypeImp::RegExpPrototypeImp(
ExecState *exec,
45 ObjectPrototypeImp *objProto,
50 setInternalValue(
String(
""));
54 static const Identifier execPropertyName(
"exec");
55 putDirect(execPropertyName,
56 new RegExpProtoFuncImp(exec,funcProto,RegExpProtoFuncImp::Exec, 0, execPropertyName), DontEnum);
57 static const Identifier testPropertyName(
"test");
58 putDirect(testPropertyName,
59 new RegExpProtoFuncImp(exec,funcProto,RegExpProtoFuncImp::Test, 0, testPropertyName), DontEnum);
60 putDirect(toStringPropertyName,
61 new RegExpProtoFuncImp(exec,funcProto,RegExpProtoFuncImp::ToString, 0, toStringPropertyName), DontEnum);
62 static const Identifier compilePropertyName(
"compile");
63 putDirect(compilePropertyName,
64 new RegExpProtoFuncImp(exec,funcProto,RegExpProtoFuncImp::Compile, 1, compilePropertyName), DontEnum);
74 putDirect(lengthPropertyName, len, DontDelete|ReadOnly|DontEnum);
78 bool RegExpProtoFuncImp::implementsCall()
const
85 if (!thisObj.inherits(&RegExpImp::info)) {
86 if (thisObj.inherits(&RegExpPrototypeImp::info)) {
88 case ToString:
return String(
"//");
91 Object err = Error::create(exec,TypeError);
92 exec->setException(err);
96 RegExpImp *reimp =
static_cast<RegExpImp*
>(thisObj.imp());
97 RegExp *re = reimp->regExp();
104 s = args[0].toString(exec);
105 int length = s.value().
size();
108 Value lastIndex = thisObj.
get(exec,
"lastIndex");
110 bool globalFlag = thisObj.
get(exec,
"global").
toBoolean(exec);
113 if (i < 0 || i > length) {
114 thisObj.
put(exec,
"lastIndex",
Number(0), DontDelete | DontEnum);
121 int **ovector = regExpObj->registerRegexp( re, s.value() );
123 re->prepareMatch(s.value());
124 str = re->match(s.value(), i, 0L, ovector);
126 regExpObj->setSubPatterns(re->subPatterns());
134 thisObj.
put(exec,
"lastIndex",
Number(0), DontDelete | DontEnum);
140 thisObj.
put(exec,
"lastIndex",
Number( (*ovector)[1] ), DontDelete | DontEnum);
141 return regExpObj->arrayOfMatches(exec,str);
161 RegExp* newEngine = RegExpObjectImp::makeEngine(exec, args[0].toString(exec), args[1]);
163 return exec->exception();
164 reimp->setRegExp(newEngine);
175 const ClassInfo RegExpImp::info = {
"RegExp", 0, 0, 0};
177 RegExpImp::RegExpImp(RegExpPrototypeImp *regexpProto)
178 : ObjectImp(regexpProto), reg(0L)
182 RegExpImp::~RegExpImp()
187 void RegExpImp::setRegExp(RegExp *r)
193 putDirect(
"global", (r->flags() & RegExp::Global) ? BooleanImp::staticTrue : BooleanImp::staticFalse,
194 DontDelete | ReadOnly | DontEnum);
195 putDirect(
"ignoreCase", (r->flags() & RegExp::IgnoreCase) ? BooleanImp::staticTrue : BooleanImp::staticFalse,
196 DontDelete | ReadOnly | DontEnum);
197 putDirect(
"multiline", (r->flags() & RegExp::Multiline) ? BooleanImp::staticTrue : BooleanImp::staticFalse,
198 DontDelete | ReadOnly | DontEnum);
200 putDirect(
"source",
new StringImp(r->pattern()), DontDelete | ReadOnly | DontEnum);
201 putDirect(
"lastIndex", NumberImp::zero(), DontDelete | DontEnum);
206 RegExpObjectImp::RegExpObjectImp(
ExecState * ,
208 RegExpPrototypeImp *regProto)
214 putDirect(prototypePropertyName, regProto, DontEnum|DontDelete|ReadOnly);
217 putDirect(lengthPropertyName, NumberImp::two(), ReadOnly|DontDelete|DontEnum);
220 RegExpObjectImp::~RegExpObjectImp()
222 delete [] lastOvector;
225 int **RegExpObjectImp::registerRegexp(
const RegExp* re,
const UString& s )
228 delete [] lastOvector;
230 lastNrSubPatterns = re->subPatterns();
240 for (
unsigned int i = 1 ; i < lastNrSubPatterns + 1 ; ++i )
242 UString substring = lastString.
substr( lastOvector[2*i], lastOvector[2*i+1] - lastOvector[2*i] );
246 arr.
put(exec,
"index",
Number(lastOvector[0]));
247 arr.
put(exec,
"input",
String(lastString));
254 if (s[0] ==
'$' && lastOvector)
260 if (i < lastNrSubPatterns + 1)
262 UString substring = lastString.
substr( lastOvector[2*i], lastOvector[2*i+1] - lastOvector[2*i] );
268 return InternalFunctionImp::get(exec, p);
274 if (s[0] ==
'$' && lastOvector) {
281 return InternalFunctionImp::hasProperty(exec, p);
284 bool RegExpObjectImp::implementsConstruct()
const
291 UString flags = flagsInput.
type() == UndefinedType ?
UString(
"") : flagsInput.toString(exec);
294 for (
int pos = 0; pos < flags.
size(); ++pos) {
295 switch (flags[pos].unicode()) {
301 Object err = Error::create(exec, SyntaxError,
302 "Invalid regular expression flags");
303 exec->setException(err);
309 bool global = (flags.
find(
"g") >= 0);
310 bool ignoreCase = (flags.
find(
"i") >= 0);
311 bool multiline = (flags.
find(
"m") >= 0);
313 int reflags = RegExp::None;
315 reflags |= RegExp::Global;
317 reflags |= RegExp::IgnoreCase;
319 reflags |= RegExp::Multiline;
321 RegExp *re =
new RegExp(p, reflags);
322 if (!re->isValid()) {
323 Object err = Error::create(exec, SyntaxError,
324 "Invalid regular expression");
325 exec->setException(err);
340 if (a0.
isA(ObjectType) && a0.
toObject(exec).inherits(&RegExpImp::info)) {
342 if (args.
size() > 1 && args[1].type() != UndefinedType) {
343 Object err = Error::create(exec,TypeError);
344 exec->setException(err);
347 RegExpImp *rimp =
static_cast<RegExpImp*
>(Object::dynamicCast(a0).imp());
348 p = rimp->regExp()->pattern();
354 RegExp* re = makeEngine(exec, p, args[1]);
356 return exec->exception().
toObject(exec);
359 RegExpImp *dat =
new RegExpImp(proto);
366 bool RegExpObjectImp::implementsCall()
const
377 return construct(exec, args);
Represents an primitive Boolean value.
Represents the current state of script execution.
Interpreter * lexicalInterpreter() const
Returns the interpreter associated with the current scope's global object.
The initial value of Function.prototype (and thus all objects created with the Function constructor)
Represents an Identifier for a Javascript object.
const UString & ustring() const
returns a UString of the identifier
Base class for all function objects.
Object builtinRegExp() const
Returns the builtin "RegExp" object.
Object builtinRegExpPrototype() const
Returns the builtin "RegExp.prototype" object.
Object builtinArray() const
Returns the builtin "Array" object.
void append(const Value &val)
Append an object to the end of the list.
Represents an primitive Null value.
Represents an primitive Number value.
Object construct(ExecState *exec, const List &args)
Creates a new object based on this object.
void put(ExecState *exec, const Identifier &propertyName, const Value &value, int attr=None)
Sets the specified property.
Value get(ExecState *exec, const Identifier &propertyName) const
Retrieves the specified property from the object.
Represents an primitive String value.
unsigned long toULong(bool *ok, bool tolerateEmptyString) const
Attempts an conversion to an unsigned long integer.
int find(const UString &f, int pos=0) const
UString substr(int pos=0, int len=-1) const
Represents an primitive Undefined value.
Value objects are act as wrappers ("smart pointers") around ValueImp objects and their descendents.
UString toString(ExecState *exec) const
Performs the ToString type conversion operation on this value (ECMA 9.8)
bool isA(Type t) const
Checks whether or not the value is of a particular tpye.
Object toObject(ExecState *exec) const
Performs the ToObject type conversion operation on this value (ECMA 9.9)
int toInt32(ExecState *exec) const
Performs the ToInt32 type conversion operation on this value (ECMA 9.5)
bool toBoolean(ExecState *exec) const
Performs the ToBoolean type conversion operation on this value (ECMA 9.2)
bool isValid() const
Returns whether or not this is a valid value.
Type type() const
Returns the type of value.