27 #include "interpreter.h"
28 #include "operations.h"
31 #include "regexp_object.h"
32 #include "error_object.h"
41 const ClassInfo RegExpPrototypeImp::info = {
"RegExp", 0, 0, 0};
43 RegExpPrototypeImp::RegExpPrototypeImp(
ExecState *exec,
44 ObjectPrototypeImp *objProto,
49 setInternalValue(
String(
""));
53 static const Identifier execPropertyName(
"exec");
54 putDirect(execPropertyName,
55 new RegExpProtoFuncImp(exec,funcProto,RegExpProtoFuncImp::Exec, 0, execPropertyName), DontEnum);
56 static const Identifier testPropertyName(
"test");
57 putDirect(testPropertyName,
58 new RegExpProtoFuncImp(exec,funcProto,RegExpProtoFuncImp::Test, 0, testPropertyName), DontEnum);
59 putDirect(toStringPropertyName,
60 new RegExpProtoFuncImp(exec,funcProto,RegExpProtoFuncImp::ToString, 0, toStringPropertyName), DontEnum);
61 static const Identifier compilePropertyName(
"compile");
62 putDirect(compilePropertyName,
63 new RegExpProtoFuncImp(exec,funcProto,RegExpProtoFuncImp::Compile, 1, compilePropertyName), DontEnum);
73 putDirect(lengthPropertyName, len, DontDelete|ReadOnly|DontEnum);
77 bool RegExpProtoFuncImp::implementsCall()
const
84 if (!thisObj.inherits(&RegExpImp::info)) {
85 if (thisObj.inherits(&RegExpPrototypeImp::info)) {
87 case ToString:
return String(
"//");
90 Object err = Error::create(exec,TypeError);
91 exec->setException(err);
95 RegExpImp *reimp =
static_cast<RegExpImp*
>(thisObj.imp());
96 RegExp *re = reimp->regExp();
103 s = args[0].toString(exec);
104 int length = s.value().
size();
107 Value lastIndex = thisObj.
get(exec,
"lastIndex");
109 bool globalFlag = thisObj.
get(exec,
"global").
toBoolean(exec);
112 if (i < 0 || i > length) {
113 thisObj.
put(exec,
"lastIndex",
Number(0), DontDelete | DontEnum);
120 int **ovector = regExpObj->registerRegexp( re, s.value() );
122 re->prepareMatch(s.value());
123 str = re->match(s.value(), i, 0L, ovector);
125 regExpObj->setSubPatterns(re->subPatterns());
133 thisObj.
put(exec,
"lastIndex",
Number(0), DontDelete | DontEnum);
139 thisObj.
put(exec,
"lastIndex",
Number( (*ovector)[1] ), DontDelete | DontEnum);
140 return regExpObj->arrayOfMatches(exec,str);
160 RegExp* newEngine = RegExpObjectImp::makeEngine(exec, args[0].toString(exec), args[1]);
162 return exec->exception();
163 reimp->setRegExp(newEngine);
174 const ClassInfo RegExpImp::info = {
"RegExp", 0, 0, 0};
176 RegExpImp::RegExpImp(RegExpPrototypeImp *regexpProto)
177 : ObjectImp(regexpProto), reg(0L)
181 RegExpImp::~RegExpImp()
186 void RegExpImp::setRegExp(RegExp *r)
192 putDirect(
"global", (r->flags() & RegExp::Global) ? BooleanImp::staticTrue : BooleanImp::staticFalse,
193 DontDelete | ReadOnly | DontEnum);
194 putDirect(
"ignoreCase", (r->flags() & RegExp::IgnoreCase) ? BooleanImp::staticTrue : BooleanImp::staticFalse,
195 DontDelete | ReadOnly | DontEnum);
196 putDirect(
"multiline", (r->flags() & RegExp::Multiline) ? BooleanImp::staticTrue : BooleanImp::staticFalse,
197 DontDelete | ReadOnly | DontEnum);
199 putDirect(
"source",
new StringImp(r->pattern()), DontDelete | ReadOnly | DontEnum);
200 putDirect(
"lastIndex", NumberImp::zero(), DontDelete | DontEnum);
205 RegExpObjectImp::RegExpObjectImp(
ExecState * ,
207 RegExpPrototypeImp *regProto)
213 putDirect(prototypePropertyName, regProto, DontEnum|DontDelete|ReadOnly);
216 putDirect(lengthPropertyName, NumberImp::two(), ReadOnly|DontDelete|DontEnum);
219 RegExpObjectImp::~RegExpObjectImp()
221 delete [] lastOvector;
224 int **RegExpObjectImp::registerRegexp(
const RegExp* re,
const UString& s )
227 delete [] lastOvector;
229 lastNrSubPatterns = re->subPatterns();
239 for (
unsigned int i = 1 ; i < lastNrSubPatterns + 1 ; ++i )
241 UString substring = lastString.
substr( lastOvector[2*i], lastOvector[2*i+1] - lastOvector[2*i] );
245 arr.
put(exec,
"index",
Number(lastOvector[0]));
246 arr.
put(exec,
"input",
String(lastString));
253 if (s[0] ==
'$' && lastOvector)
259 if (i < lastNrSubPatterns + 1)
261 UString substring = lastString.
substr( lastOvector[2*i], lastOvector[2*i+1] - lastOvector[2*i] );
267 return InternalFunctionImp::get(exec, p);
273 if (s[0] ==
'$' && lastOvector) {
280 return InternalFunctionImp::hasProperty(exec, p);
283 bool RegExpObjectImp::implementsConstruct()
const
290 UString flags = flagsInput.
type() == UndefinedType ?
UString(
"") : flagsInput.toString(exec);
293 for (
int pos = 0; pos < flags.
size(); ++pos) {
294 switch (flags[pos].unicode()) {
300 Object err = Error::create(exec, SyntaxError,
301 "Invalid regular expression flags");
302 exec->setException(err);
308 bool global = (flags.
find(
"g") >= 0);
309 bool ignoreCase = (flags.
find(
"i") >= 0);
310 bool multiline = (flags.
find(
"m") >= 0);
312 int reflags = RegExp::None;
314 reflags |= RegExp::Global;
316 reflags |= RegExp::IgnoreCase;
318 reflags |= RegExp::Multiline;
320 RegExp *re =
new RegExp(p, reflags);
321 if (!re->isValid()) {
322 Object err = Error::create(exec, SyntaxError,
323 "Invalid regular expression");
324 exec->setException(err);
339 if (a0.
isA(ObjectType) && a0.
toObject(exec).inherits(&RegExpImp::info)) {
341 if (args.
size() > 1 && args[1].type() != UndefinedType) {
342 Object err = Error::create(exec,TypeError);
343 exec->setException(err);
346 RegExpImp *rimp =
static_cast<RegExpImp*
>(Object::dynamicCast(a0).imp());
347 p = rimp->regExp()->pattern();
353 RegExp* re = makeEngine(exec, p, args[1]);
355 return exec->exception().
toObject(exec);
358 RegExpImp *dat =
new RegExpImp(proto);
365 bool RegExpObjectImp::implementsCall()
const
376 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.