Switch to edit mode.
Name(s): end_expression1: ":end_expression(string[,stop_at])"
2: " assumes string starts with an expression; returns the index of the last char in expression or 0 if string appears not to be an expression. Expression ends at any character from stop_at which occurs at top level."
3: string = args[1]
4: stop_at = {@args, " "}[2]
5: gone = 0
6: paren_stack = ""
7: inquote = 0
8: search = top_level_search = "[][{}()\"" + strsub(stop_at, "]", "") + "]"
9: paren_search = "[][{}()\"]"
10: while (m = match(string, search))
11: char = string[m[1]]
12: string[1..m[2]] = ""
13: gone = gone + m[2]
14: if (char == "\"")
15: "...skip over quoted string..."
16: char = "\\"
17: while (char == "\\")
18: if (!(m = match(string, "%(\\.?%|\"%)")))
19: return 0
20: endif
21: char = string[m[1]]
22: string[1..m[2]] = ""
23: gone = gone + m[2]
24: endwhile
25: elseif (index("([{", char))
26: "... push parenthesis..."
27: paren_stack[1..0] = char
28: search = paren_search
29: elseif (i = index(")]}", char))
30: if (paren_stack && "([{"[i] == paren_stack[1])
31: "... pop parenthesis..."
32: paren_stack[1..1] = ""
33: search = paren_stack ? paren_search | top_level_search
34: else
35: "...parenthesis mismatch..."
36: return 0
37: endif
38: else
39: "... stop character ..."
40: return gone - 1
41: endif
42: endwhile
43: return !paren_stack && gone + length(string)