builtin_regexp.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. package otto
  2. import (
  3. "fmt"
  4. )
  5. // RegExp
  6. func builtinRegExp(call FunctionCall) Value {
  7. pattern := call.Argument(0)
  8. flags := call.Argument(1)
  9. if obj := pattern.object(); obj != nil {
  10. if obj.class == classRegExpName && flags.IsUndefined() {
  11. return pattern
  12. }
  13. }
  14. return objectValue(call.runtime.newRegExp(pattern, flags))
  15. }
  16. func builtinNewRegExp(obj *object, argumentList []Value) Value {
  17. return objectValue(obj.runtime.newRegExp(
  18. valueOfArrayIndex(argumentList, 0),
  19. valueOfArrayIndex(argumentList, 1),
  20. ))
  21. }
  22. func builtinRegExpToString(call FunctionCall) Value {
  23. thisObject := call.thisObject()
  24. source := thisObject.get("source").string()
  25. flags := []byte{}
  26. if thisObject.get("global").bool() {
  27. flags = append(flags, 'g')
  28. }
  29. if thisObject.get("ignoreCase").bool() {
  30. flags = append(flags, 'i')
  31. }
  32. if thisObject.get("multiline").bool() {
  33. flags = append(flags, 'm')
  34. }
  35. return stringValue(fmt.Sprintf("/%s/%s", source, flags))
  36. }
  37. func builtinRegExpExec(call FunctionCall) Value {
  38. thisObject := call.thisObject()
  39. target := call.Argument(0).string()
  40. match, result := execRegExp(thisObject, target)
  41. if !match {
  42. return nullValue
  43. }
  44. return objectValue(execResultToArray(call.runtime, target, result))
  45. }
  46. func builtinRegExpTest(call FunctionCall) Value {
  47. thisObject := call.thisObject()
  48. target := call.Argument(0).string()
  49. match, result := execRegExp(thisObject, target)
  50. if !match {
  51. return boolValue(match)
  52. }
  53. // Match extract and assign input, $_ and $1 -> $9 on global RegExp.
  54. input := stringValue(target)
  55. call.runtime.global.RegExp.defineProperty("$_", input, 0o100, false)
  56. call.runtime.global.RegExp.defineProperty("input", input, 0o100, false)
  57. var start int
  58. n := 1
  59. re := call.runtime.global.RegExp
  60. empty := stringValue("")
  61. for i, v := range result[2:] {
  62. if i%2 == 0 {
  63. start = v
  64. } else {
  65. if v == -1 {
  66. // No match for this part.
  67. re.defineProperty(fmt.Sprintf("$%d", n), empty, 0o100, false)
  68. } else {
  69. re.defineProperty(fmt.Sprintf("$%d", n), stringValue(target[start:v]), 0o100, false)
  70. }
  71. n++
  72. if n == 10 {
  73. break
  74. }
  75. }
  76. }
  77. if n <= 9 {
  78. // Erase remaining.
  79. for i := n; i <= 9; i++ {
  80. re.defineProperty(fmt.Sprintf("$%d", i), empty, 0o100, false)
  81. }
  82. }
  83. return boolValue(match)
  84. }
  85. func builtinRegExpCompile(call FunctionCall) Value {
  86. // This (useless) function is deprecated, but is here to provide some
  87. // semblance of compatibility.
  88. // Caveat emptor: it may not be around for long.
  89. return Value{}
  90. }