<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
	<channel>
		<title><![CDATA[Серый форум &mdash; AHK: JSON.parse при true возвращрает -1 (ScriptControl)]]></title>
		<link>https://forum.script-coding.com/viewtopic.php?id=17236</link>
		<atom:link href="https://forum.script-coding.com/extern.php?action=feed&amp;tid=17236&amp;type=rss" rel="self" type="application/rss+xml" />
		<description><![CDATA[Недавние сообщения в теме «AHK: JSON.parse при true возвращрает -1 (ScriptControl)».]]></description>
		<lastBuildDate>Sun, 10 Jul 2022 15:20:17 +0000</lastBuildDate>
		<generator>PunBB</generator>
		<item>
			<title><![CDATA[Re: AHK: JSON.parse при true возвращрает -1 (ScriptControl)]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=153851#p153851</link>
			<description><![CDATA[<p>Он медленный и в нем были баги.</p>]]></description>
			<author><![CDATA[null@example.com (Malcev)]]></author>
			<pubDate>Sun, 10 Jul 2022 15:20:17 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=153851#p153851</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: JSON.parse при true возвращрает -1 (ScriptControl)]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=153834#p153834</link>
			<description><![CDATA[<p>Вот не помню где брал, но всегда им пользуюсь и четко работает.</p><div class="codebox"><pre><code>/**
 * Lib: JSON.ahk
 *     JSON lib for AutoHotkey.
 * Version:
 *     v2.1.3 [updated 04/18/2016 (MM/DD/YYYY)]
 * License:
 *     WTFPL [http://wtfpl.net/]
 * Requirements:
 *     Latest version of AutoHotkey (v1.1+ or v2.0-a+)
 * Installation:
 *     Use #Include JSON.ahk or copy into a function library folder and then
 *     use #Include &lt;JSON&gt;
 * Links:
 *     GitHub:     - https://github.com/cocobelgica/AutoHotkey-JSON
 *     Forum Topic - http://goo.gl/r0zI8t
 *     Email:      - cocobelgica &lt;at&gt; gmail &lt;dot&gt; com
 */


/**
 * Class: JSON
 *     The JSON object contains methods for parsing JSON and converting values
 *     to JSON. Callable - NO; Instantiable - YES; Subclassable - YES;
 *     Nestable(via #Include) - NO.
 * Methods:
 *     Load() - see relevant documentation before method definition header
 *     Dump() - see relevant documentation before method definition header
 */
class JSON
{
	/**
	 * Method: Load
	 *     Parses a JSON string into an AHK value
	 * Syntax:
	 *     value := JSON.Load( text [, reviver ] )
	 * Parameter(s):
	 *     value      [retval] - parsed value
	 *     text    [in, ByRef] - JSON formatted string
	 *     reviver   [in, opt] - function object, similar to JavaScript&#039;s
	 *                           JSON.parse() &#039;reviver&#039; parameter
	 */
	class Load extends JSON.Functor
	{
		Call(self, ByRef text, reviver:=&quot;&quot;)
		{
			this.rev := IsObject(reviver) ? reviver : false
		; Object keys(and array indices) are temporarily stored in arrays so that
		; we can enumerate them in the order they appear in the document/text instead
		; of alphabetically. Skip if no reviver function is specified.
			this.keys := this.rev ? {} : false

			static quot := Chr(34), bashq := &quot;\&quot; . quot
			     , json_value := quot . &quot;{[01234567890-tfn&quot;
			     , json_value_or_array_closing := quot . &quot;{[]01234567890-tfn&quot;
			     , object_key_or_object_closing := quot . &quot;}&quot;

			key := &quot;&quot;
			is_key := false
			root := {}
			stack := [root]
			next := json_value
			pos := 0

			while ((ch := SubStr(text, ++pos, 1)) != &quot;&quot;) {
				if InStr(&quot; `t`r`n&quot;, ch)
					continue
				if !InStr(next, ch, 1)
					this.ParseError(next, text, pos)

				holder := stack[1]
				is_array := holder.IsArray

				if InStr(&quot;,:&quot;, ch) {
					next := (is_key := !is_array &amp;&amp; ch == &quot;,&quot;) ? quot : json_value

				} else if InStr(&quot;}]&quot;, ch) {
					ObjRemoveAt(stack, 1)
					next := stack[1]==root ? &quot;&quot; : stack[1].IsArray ? &quot;,]&quot; : &quot;,}&quot;

				} else {
					if InStr(&quot;{[&quot;, ch) {
					; Check if Array() is overridden and if its return value has
					; the &#039;IsArray&#039; property. If so, Array() will be called normally,
					; otherwise, use a custom base object for arrays
						static json_array := Func(&quot;Array&quot;).IsBuiltIn || ![].IsArray ? {IsArray: true} : 0
					
					; sacrifice readability for minor(actually negligible) performance gain
						(ch == &quot;{&quot;)
							? ( is_key := true
							  , value := {}
							  , next := object_key_or_object_closing )
						; ch == &quot;[&quot;
							: ( value := json_array ? new json_array : []
							  , next := json_value_or_array_closing )
						
						ObjInsertAt(stack, 1, value)

						if (this.keys)
							this.keys[value] := []
					
					} else {
						if (ch == quot) {
							i := pos
							while (i := InStr(text, quot,, i+1)) {
								value := StrReplace(SubStr(text, pos+1, i-pos-1), &quot;\\&quot;, &quot;\u005c&quot;)

								static tail := A_AhkVersion&lt;&quot;2&quot; ? 0 : -1
								if (SubStr(value, tail) != &quot;\&quot;)
									break
							}

							if (!i)
								this.ParseError(&quot;&#039;&quot;, text, pos)

							  value := StrReplace(value,  &quot;\/&quot;,  &quot;/&quot;)
							, value := StrReplace(value, bashq, quot)
							, value := StrReplace(value,  &quot;\b&quot;, &quot;`b&quot;)
							, value := StrReplace(value,  &quot;\f&quot;, &quot;`f&quot;)
							, value := StrReplace(value,  &quot;\n&quot;, &quot;`n&quot;)
							, value := StrReplace(value,  &quot;\r&quot;, &quot;`r&quot;)
							, value := StrReplace(value,  &quot;\t&quot;, &quot;`t&quot;)

							pos := i ; update pos
							
							i := 0
							while (i := InStr(value, &quot;\&quot;,, i+1)) {
								if !(SubStr(value, i+1, 1) == &quot;u&quot;)
									this.ParseError(&quot;\&quot;, text, pos - StrLen(SubStr(value, i+1)))

								uffff := Abs(&quot;0x&quot; . SubStr(value, i+2, 4))
								if (A_IsUnicode || uffff &lt; 0x100)
									value := SubStr(value, 1, i-1) . Chr(uffff) . SubStr(value, i+6)
							}

							if (is_key) {
								key := value, next := &quot;:&quot;
								continue
							}
						
						} else {
							value := SubStr(text, pos, i := RegExMatch(text, &quot;[\]\},\s]|$&quot;,, pos)-pos)

							static number := &quot;number&quot;, integer :=&quot;integer&quot;
							if value is %number%
							{
								if value is %integer%
									value += 0
							}
							else if (value == &quot;true&quot; || value == &quot;false&quot;)
								value := %value% + 0
							else if (value == &quot;null&quot;)
								value := &quot;&quot;
							else
							; we can do more here to pinpoint the actual culprit
							; but that&#039;s just too much extra work.
								this.ParseError(next, text, pos, i)

							pos += i-1
						}

						next := holder==root ? &quot;&quot; : is_array ? &quot;,]&quot; : &quot;,}&quot;
					} ; If InStr(&quot;{[&quot;, ch) { ... } else

					is_array? key := ObjPush(holder, value) : holder[key] := value

					if (this.keys &amp;&amp; this.keys.HasKey(holder))
						this.keys[holder].Push(key)
				}
			
			} ; while ( ... )

			return this.rev ? this.Walk(root, &quot;&quot;) : root[&quot;&quot;]
		}

		ParseError(expect, ByRef text, pos, len:=1)
		{
			static quot := Chr(34), qurly := quot . &quot;}&quot;
			
			line := StrSplit(SubStr(text, 1, pos), &quot;`n&quot;, &quot;`r&quot;).Length()
			col := pos - InStr(text, &quot;`n&quot;,, -(StrLen(text)-pos+1))
			msg := Format(&quot;{1}`n`nLine:`t{2}`nCol:`t{3}`nChar:`t{4}&quot;
			,     (expect == &quot;&quot;)     ? &quot;Extra data&quot;
			    : (expect == &quot;&#039;&quot;)    ? &quot;Unterminated string starting at&quot;
			    : (expect == &quot;\&quot;)    ? &quot;Invalid \escape&quot;
			    : (expect == &quot;:&quot;)    ? &quot;Expecting &#039;:&#039; delimiter&quot;
			    : (expect == quot)   ? &quot;Expecting object key enclosed in double quotes&quot;
			    : (expect == qurly)  ? &quot;Expecting object key enclosed in double quotes or object closing &#039;}&#039;&quot;
			    : (expect == &quot;,}&quot;)   ? &quot;Expecting &#039;,&#039; delimiter or object closing &#039;}&#039;&quot;
			    : (expect == &quot;,]&quot;)   ? &quot;Expecting &#039;,&#039; delimiter or array closing &#039;]&#039;&quot;
			    : InStr(expect, &quot;]&quot;) ? &quot;Expecting JSON value or array closing &#039;]&#039;&quot;
			    :                      &quot;Expecting JSON value(string, number, true, false, null, object or array)&quot;
			, line, col, pos)

			static offset := A_AhkVersion&lt;&quot;2&quot; ? -3 : -4
			throw Exception(msg, offset, SubStr(text, pos, len))
		}

		Walk(holder, key)
		{
			value := holder[key]
			if IsObject(value) {
				for i, k in this.keys[value] {
					; check if ObjHasKey(value, k) ??
					v := this.Walk(value, k)
					if (v != JSON.Undefined)
						value[k] := v
					else
						ObjDelete(value, k)
				}
			}
			
			return this.rev.Call(holder, key, value)
		}
	}

	/**
	 * Method: Dump
	 *     Converts an AHK value into a JSON string
	 * Syntax:
	 *     str := JSON.Dump( value [, replacer, space ] )
	 * Parameter(s):
	 *     str        [retval] - JSON representation of an AHK value
	 *     value          [in] - any value(object, string, number)
	 *     replacer  [in, opt] - function object, similar to JavaScript&#039;s
	 *                           JSON.stringify() &#039;replacer&#039; parameter
	 *     space     [in, opt] - similar to JavaScript&#039;s JSON.stringify()
	 *                           &#039;space&#039; parameter
	 */
	class Dump extends JSON.Functor
	{
		Call(self, value, replacer:=&quot;&quot;, space:=&quot;&quot;)
		{
			this.rep := IsObject(replacer) ? replacer : &quot;&quot;

			this.gap := &quot;&quot;
			if (space) {
				static integer := &quot;integer&quot;
				if space is %integer%
					Loop, % ((n := Abs(space))&gt;10 ? 10 : n)
						this.gap .= &quot; &quot;
				else
					this.gap := SubStr(space, 1, 10)

				this.indent := &quot;`n&quot;
			}

			return this.Str({&quot;&quot;: value}, &quot;&quot;)
		}

		Str(holder, key)
		{
			value := holder[key]

			if (this.rep)
				value := this.rep.Call(holder, key, ObjHasKey(holder, key) ? value : JSON.Undefined)

			if IsObject(value) {
			; Check object type, skip serialization for other object types such as
			; ComObject, Func, BoundFunc, FileObject, RegExMatchObject, Property, etc.
				static type := A_AhkVersion&lt;&quot;2&quot; ? &quot;&quot; : Func(&quot;Type&quot;)
				if (type ? type.Call(value) == &quot;Object&quot; : ObjGetCapacity(value) != &quot;&quot;) {
					if (this.gap) {
						stepback := this.indent
						this.indent .= this.gap
					}

					is_array := value.IsArray
				; Array() is not overridden, rollback to old method of
				; identifying array-like objects. Due to the use of a for-loop
				; sparse arrays such as &#039;[1,,3]&#039; are detected as objects({}). 
					if (!is_array) {
						for i in value
							is_array := i == A_Index
						until !is_array
					}

					str := &quot;&quot;
					if (is_array) {
						Loop, % value.Length() {
							if (this.gap)
								str .= this.indent
							
							v := this.Str(value, A_Index)
							str .= (v != &quot;&quot;) ? v . &quot;,&quot; : &quot;null,&quot;
						}
					} else {
						colon := this.gap ? &quot;: &quot; : &quot;:&quot;
						for k in value {
							v := this.Str(value, k)
							if (v != &quot;&quot;) {
								if (this.gap)
									str .= this.indent

								str .= this.Quote(k) . colon . v . &quot;,&quot;
							}
						}
					}

					if (str != &quot;&quot;) {
						str := RTrim(str, &quot;,&quot;)
						if (this.gap)
							str .= stepback
					}

					if (this.gap)
						this.indent := stepback

					return is_array ? &quot;[&quot; . str . &quot;]&quot; : &quot;{&quot; . str . &quot;}&quot;
				}
			
			} else ; is_number ? value : &quot;value&quot;
				return ObjGetCapacity([value], 1)==&quot;&quot; ? value : this.Quote(value)
		}

		Quote(string)
		{
			static quot := Chr(34), bashq := &quot;\&quot; . quot

			if (string != &quot;&quot;) {
				  string := StrReplace(string,  &quot;\&quot;,  &quot;\\&quot;)
				; , string := StrReplace(string,  &quot;/&quot;,  &quot;\/&quot;) ; optional in ECMAScript
				, string := StrReplace(string, quot, bashq)
				, string := StrReplace(string, &quot;`b&quot;,  &quot;\b&quot;)
				, string := StrReplace(string, &quot;`f&quot;,  &quot;\f&quot;)
				, string := StrReplace(string, &quot;`n&quot;,  &quot;\n&quot;)
				, string := StrReplace(string, &quot;`r&quot;,  &quot;\r&quot;)
				, string := StrReplace(string, &quot;`t&quot;,  &quot;\t&quot;)

				static rx_escapable := A_AhkVersion&lt;&quot;2&quot; ? &quot;O)[^\x20-\x7e]&quot; : &quot;[^\x20-\x7e]&quot;
				while RegExMatch(string, rx_escapable, m)
					string := StrReplace(string, m.Value, Format(&quot;\u{1:04x}&quot;, Ord(m.Value)))
			}

			return quot . string . quot
		}
	}

	/**
	 * Property: Undefined
	 *     Proxy for &#039;undefined&#039; type
	 * Syntax:
	 *     undefined := JSON.Undefined
	 * Remarks:
	 *     For use with reviver and replacer functions since AutoHotkey does not
	 *     have an &#039;undefined&#039; type. Returning blank(&quot;&quot;) or 0 won&#039;t work since these
	 *     can&#039;t be distnguished from actual JSON values. This leaves us with objects.
	 *     Replacer() - the caller may return a non-serializable AHK objects such as
	 *     ComObject, Func, BoundFunc, FileObject, RegExMatchObject, and Property to
	 *     mimic the behavior of returning &#039;undefined&#039; in JavaScript but for the sake
	 *     of code readability and convenience, it&#039;s better to do &#039;return JSON.Undefined&#039;.
	 *     Internally, the property returns a ComObject with the variant type of VT_EMPTY.
	 */
	Undefined[]
	{
		get {
			static empty := {}, vt_empty := ComObject(0, &amp;empty, 1)
			return vt_empty
		}
	}

	class Functor
	{
		__Call(method, ByRef arg, args*)
		{
		; When casting to Call(), use a new instance of the &quot;function object&quot;
		; so as to avoid directly storing the properties(used across sub-methods)
		; into the &quot;function object&quot; itself.
			if IsObject(method)
				return (new this).Call(method, arg, args*)
			else if (method == &quot;&quot;)
				return (new this).Call(arg, args*)
		}
	}
}</code></pre></div>]]></description>
			<author><![CDATA[null@example.com (andrey.a.polyakov.b2c)]]></author>
			<pubDate>Sat, 09 Jul 2022 06:22:24 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=153834#p153834</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: JSON.parse при true возвращрает -1 (ScriptControl)]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=153832#p153832</link>
			<description><![CDATA[<p>Я не увидел потенциальных проблем.</p>]]></description>
			<author><![CDATA[null@example.com (teadrinker)]]></author>
			<pubDate>Fri, 08 Jul 2022 18:16:25 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=153832#p153832</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: JSON.parse при true возвращрает -1 (ScriptControl)]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=153831#p153831</link>
			<description><![CDATA[<p>Я вынес код в <strong>if</strong> и сделал <strong>SC</strong> статичной, дабы не создавало каждый раз новый COM объект, и вопрос в том, не возникнет ли с этим проблем? По моим отдаленным тестам скорости, мой код стал работать в десятки раз быстрее при последующих вызовах, но вот не вылезут ли какие-то проблемы с этим я не знаю. Ибо не работал с COM объектом ScriptControl, примерно я понимаю как это работает на стороне JS.</p>]]></description>
			<author><![CDATA[null@example.com (Phoenixxx_Czar)]]></author>
			<pubDate>Fri, 08 Jul 2022 17:52:50 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=153831#p153831</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: JSON.parse при true возвращрает -1 (ScriptControl)]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=153830#p153830</link>
			<description><![CDATA[<p>Опять непонятно, в чём вопрос. Можно ли это использовать отдельно от класса, или что?</p>]]></description>
			<author><![CDATA[null@example.com (teadrinker)]]></author>
			<pubDate>Fri, 08 Jul 2022 17:04:17 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=153830#p153830</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: JSON.parse при true возвращрает -1 (ScriptControl)]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=153829#p153829</link>
			<description><![CDATA[<p>Вопросик еще будет по этой функции, можно ли сделать так и будет ли это правильно работать и быть эффективным?</p><div class="codebox"><pre><code>parse(jsonStr)
{
	static SC

	if (!SC)
	{
		SC := ComObjCreate(&quot;ScriptControl&quot;)
		SC.Language := &quot;JScript&quot;
		ComObjError(false)
	
		jsCode =
		(
			function arrangeForAhkTraversing(a) {
				if (a instanceof Array) {
					for (var b = 0; b &lt; a.length; ++b) a[b] = arrangeForAhkTraversing(a[b]);
					return [&quot;array&quot;, a];
				}
				if (a instanceof Object) {
					var c = [],
						d = [];
					for (var e in a) c.push(e), d.push(arrangeForAhkTraversing(a[e]));
					return [&quot;object&quot;, [c, d]];
				}
				return &quot;boolean&quot; == typeof a ? [&quot;boolean&quot;, parseInt(Number(a))] : [typeof a, a];
			}
		)

		SC.ExecuteStatement(jsCode)
	}

	return this._convertJScriptObjToAhks(SC.Eval(&quot;arrangeForAhkTraversing(&quot; jsonStr &quot;)&quot;))
}</code></pre></div>]]></description>
			<author><![CDATA[null@example.com (Phoenixxx_Czar)]]></author>
			<pubDate>Fri, 08 Jul 2022 16:32:09 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=153829#p153829</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: JSON.parse при true возвращрает -1 (ScriptControl)]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=153828#p153828</link>
			<description><![CDATA[<p>Предполагаю, что этот вариант не подойдёт ТС, только что проверил, что он не работает на ANSI.</p>]]></description>
			<author><![CDATA[null@example.com (teadrinker)]]></author>
			<pubDate>Fri, 08 Jul 2022 16:12:44 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=153828#p153828</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: JSON.parse при true возвращрает -1 (ScriptControl)]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=153825#p153825</link>
			<description><![CDATA[<p>Единственно нормально работающий json парсер на ахк это этот:<br /><a href="https://www.autohotkey.com/boards/viewtopic.php?f=6&amp;t=92320">https://www.autohotkey.com/boards/viewt … mp;t=92320</a></p>]]></description>
			<author><![CDATA[null@example.com (Malcev)]]></author>
			<pubDate>Fri, 08 Jul 2022 15:32:14 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=153825#p153825</guid>
		</item>
		<item>
			<title><![CDATA[Re: AHK: JSON.parse при true возвращрает -1 (ScriptControl)]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=153824#p153824</link>
			<description><![CDATA[<p>Можно сделать некий костыль, в виде преобразование в Number и потом преобразовать в int:<br /></p><div class="codebox"><pre><code>return &quot;boolean&quot; == typeof a ? [&quot;boolean&quot;, parseInt(Number(a))] : [typeof a, a];</code></pre></div><div class="codebox"><pre><code>class JSON
{
	parse(jsonStr)
	{
		SC := ComObjCreate(&quot;ScriptControl&quot;)
		SC.Language := &quot;JScript&quot;
		ComObjError(false)

		jsCode =
		(
			function arrangeForAhkTraversing(a) {
				if (a instanceof Array) {
					for (var b = 0; b &lt; a.length; ++b) a[b] = arrangeForAhkTraversing(a[b]);
					return [&quot;array&quot;, a];
				}
				if (a instanceof Object) {
					var c = [],
						d = [];
					for (var e in a) c.push(e), d.push(arrangeForAhkTraversing(a[e]));
					return [&quot;object&quot;, [c, d]];
				}
				return &quot;boolean&quot; == typeof a ? [&quot;boolean&quot;, parseInt(Number(a))] : [typeof a, a];
			}
		)

		SC.ExecuteStatement(jsCode &quot;; obj=&quot; jsonStr)
		return this._convertJScriptObjToAhks( SC.Eval(&quot;arrangeForAhkTraversing(obj)&quot;) )
	}

	stringify(value, space := 0, _indent := 1)
	{
		_space := space
		if (space ~= &quot;^\d+$&quot;)
		{
			_space := this._strRepeat(A_Space, space)
		}

		str := &quot;&quot;
		array := true
		for k in value
		{
			if (k == A_Index)
			{
				continue
			}

			array := false
			break
		}

		indent := _indent
		for a, b in value
		{
			if (space)
			{
				str .= this._strRepeat(_space, indent)
			}

			str .= (array ? &quot;&quot; : &quot;&quot;&quot;&quot; a &quot;&quot;&quot;: &quot;)

			if (IsObject(b))
			{
				if (space)
				{
					str := RTrim(str, &quot; &quot;) &quot;`n&quot; this._strRepeat(_space, indent)
				}

				str .= this.stringify(b, space, indent + 1)
			}
			else
			{
				str .= (b ~= &quot;^\d+$&quot; ? b : &quot;&quot;&quot;&quot; strReplace(strReplace(b, &quot;\&quot;, &quot;\\&quot;), &quot;&quot;&quot;&quot;, &quot;\&quot;&quot;&quot;) &quot;&quot;&quot;&quot;)
			}

			str .= &quot;,&quot; (space ? &quot;`n&quot; : &quot; &quot;)
		}
		str := RTrim(str, &quot; ,`n&quot;)
		str := regExReplace(str, &quot;`n([\s]+)?`n&quot;, &quot;`n&quot;)

		indent--
		out := (array ? &quot;[&quot; : &quot;{&quot;) (str ? (space ? &quot;`n&quot; : &quot;&quot;) str (space ? &quot;`n&quot; : &quot;&quot;) (space ? this._strRepeat(_space, indent) : &quot;&quot;)  : &quot;&quot;) (array ? &quot;]&quot; : &quot;}&quot;)

		out := regExReplace(out, &quot;^(\h*(\R|$))+|\R\h*(?=\R|$)&quot;)
		out := regExReplace(out, &quot;:\n\s{1,}\[\]&quot;, &quot;: []&quot;)
		out := regExReplace(out, &quot;:\n\s{1,}\{\}&quot;, &quot;: {}&quot;)

		return out
	}

	_convertJScriptObjToAhks(jsObj)
	{
		if (jsObj[0] == &quot;object&quot;)
		{
			obj := {}, keys := jsObj[1][0], values := jsObj[1][1]
			loop % keys.length
			{
				obj[keys[A_INDEX-1]] := this._convertJScriptObjToAhks( values[A_INDEX-1] )
			}
			return obj
		}
		else if (jsObj[0] == &quot;array&quot;)
		{
			array := []
			loop % jsObj[1].length
			{
				array.insert(this._convertJScriptObjToAhks( jsObj[1][A_INDEX-1] ))
			}
			return array
		}
		else
		{
			return jsObj[1]
		}
	}

	_strRepeat(str, count)
	{
		return strReplace(Format(&quot;{:&quot; count &quot;}&quot;, &quot;&quot;), &quot; &quot;, str)
	}
}
</code></pre></div><p>В таком виде я получаю довольно ожидаемый результат.</p>]]></description>
			<author><![CDATA[null@example.com (Phoenixxx_Czar)]]></author>
			<pubDate>Fri, 08 Jul 2022 14:00:05 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=153824#p153824</guid>
		</item>
		<item>
			<title><![CDATA[AHK: JSON.parse при true возвращрает -1 (ScriptControl)]]></title>
			<link>https://forum.script-coding.com/viewtopic.php?pid=153823#p153823</link>
			<description><![CDATA[<div class="codebox"><pre><code>class JSON
{
	parse(jsonStr)
	{
		SC := ComObjCreate(&quot;ScriptControl&quot;)
		SC.Language := &quot;JScript&quot;
		ComObjError(false)

		jsCode := &quot;function arrangeForAhkTraversing(r){if(r instanceof Array){for(var a=0;a&lt;r.length;++a)r[a]=arrangeForAhkTraversing(r[a]);return[&#039;array&#039;,r]}if(r instanceof Object){var n=[],e=[];for(var o in r)n.push(o),e.push(arrangeForAhkTraversing(r[o]));return[&#039;object&#039;,[n,e]]}return[typeof r,r]}&quot;

		SC.ExecuteStatement(jsCode &quot;; obj=&quot; jsonStr)
		return this._convertJScriptObjToAhks( SC.Eval(&quot;arrangeForAhkTraversing(obj)&quot;) )
	}

	stringify(value, space := 0, _indent := 1)
	{
		_space := space
		if (space ~= &quot;^\d+$&quot;)
		{
			_space := this._strRepeat(A_Space, space)
		}

		str := &quot;&quot;
		array := true
		for k in value
		{
			if (k == A_Index)
			{
				continue
			}

			array := false
			break
		}

		indent := _indent
		for a, b in value
		{
			if (space)
			{
				str .= this._strRepeat(_space, indent)
			}

			str .= (array ? &quot;&quot; : &quot;&quot;&quot;&quot; a &quot;&quot;&quot;: &quot;)

			if (IsObject(b))
			{
				if (space)
				{
					str := RTrim(str, &quot; &quot;) &quot;`n&quot; this._strRepeat(_space, indent)
				}

				str .= this.stringify(b, space, indent + 1)
			}
			else
			{
				str .= (b ~= &quot;^\d+$&quot; ? b : &quot;&quot;&quot;&quot; strReplace(strReplace(b, &quot;\&quot;, &quot;\\&quot;), &quot;&quot;&quot;&quot;, &quot;\&quot;&quot;&quot;) &quot;&quot;&quot;&quot;)
			}

			str .= &quot;,&quot; (space ? &quot;`n&quot; : &quot; &quot;)
		}
		str := RTrim(str, &quot; ,`n&quot;)
		str := regExReplace(str, &quot;`n([\s]+)?`n&quot;, &quot;`n&quot;)

		indent--
		out := (array ? &quot;[&quot; : &quot;{&quot;) (str ? (space ? &quot;`n&quot; : &quot;&quot;) str (space ? &quot;`n&quot; : &quot;&quot;) (space ? this._strRepeat(_space, indent) : &quot;&quot;)  : &quot;&quot;) (array ? &quot;]&quot; : &quot;}&quot;)

		out := regExReplace(out, &quot;^(\h*(\R|$))+|\R\h*(?=\R|$)&quot;)
		out := regExReplace(out, &quot;:\n\s{1,}\[\]&quot;, &quot;: []&quot;)
		out := regExReplace(out, &quot;:\n\s{1,}\{\}&quot;, &quot;: {}&quot;)

		return out
	}

	_convertJScriptObjToAhks(jsObj)
	{
		if (jsObj[0] == &quot;object&quot;)
		{
			obj := {}, keys := jsObj[1][0], values := jsObj[1][1]
			loop % keys.length
			{
				obj[keys[A_INDEX-1]] := this._convertJScriptObjToAhks( values[A_INDEX-1] )
			}
			return obj
		}
		else if (jsObj[0] == &quot;array&quot;)
		{
			array := []
			loop % jsObj[1].length
			{
				array.insert(this._convertJScriptObjToAhks( jsObj[1][A_INDEX-1] ))
			}
			return array
		}
		else
		{
			return jsObj[1]
		}
	}

	_strRepeat(str, count)
	{
		return strReplace(Format(&quot;{:&quot; count &quot;}&quot;, &quot;&quot;), &quot; &quot;, str)
	}
}
</code></pre></div><p>При этом коде я получаю &quot;-1&quot;, почему?<br /></p><div class="codebox"><pre><code>str = {&quot;test&quot;: true}

msgbox, % JSON.parse(str).test</code></pre></div>]]></description>
			<author><![CDATA[null@example.com (Phoenixxx_Czar)]]></author>
			<pubDate>Fri, 08 Jul 2022 01:13:27 +0000</pubDate>
			<guid>https://forum.script-coding.com/viewtopic.php?pid=153823#p153823</guid>
		</item>
	</channel>
</rss>
