TESTS: added more dynamic method invocations tests. TESTS: duplicated COPY and IN tests to in-function context.

Red [
	Title:   "Red/System object! datatype test script"
	Author:  "Nenad Rakocevic & Peter W A Wood"
	File: 	 %object-test.red
	Version: "0.1.0"
	Tabs:	 4
	Rights:  "Copyright (C) 2011-2014 Nenad Rakocevic & Peter W A Wood. All rights reserved."
	License: "BSD-3 - https://github.com/dockimbel/Red/blob/origin/BSD-3-License.txt"
]

#include  %../../../quick-test/quick-test.red

~~~start-file~~~ "object"

===start-group=== "basic tests"

	--test-- "basic-1"
		obj1: context []
		--assert "make object! []" = mold obj1

	--test-- "basic-2"
		obj2: object []
		--assert "make object! []" = mold obj2

	--test-- "basic-3"
		obj3: make object! []
		--assert "make object! []" = mold obj3

	--test-- "basic-4"
		blk: []
		obj4: object blk
		--assert "make object! []" = mold obj4

	--test-- "basic-5"
		obj5: object [
			a: 123
			show: does [a + 1]
			reset: does [a: none]
			--assert show = 124
			--assert a = 123
		]
		--assert obj5/show = 124
		obj5/reset
		--assert none? obj5/a

	--test-- "basic-6"
		obj5/a: 456
		--assert obj5/a = 456

	--test-- "basic-7"
		--assert find obj5 'a
		--assert not find obj5 'z
		--assert 456 = select obj5 'a
		--assert none? select obj5 'z

	--test-- "basic-8"
		obj8: context [
			b: 123
			a: object [
				b: 456
				double: does [b * 2]
				set-b: does [b: 'hello]
			]
		]
		--assert obj8/b = 123
		--assert obj8/a/b = 456
		--assert obj8/a/double = 912
		obj8/a/set-b
		--assert obj8/a/b = 'hello

	--test-- "basic-9"
		obj8/a/b: 'red
		--assert obj8/a/b = 'red

	--test-- "basic-10"
		obj10: object [
			a: 1
			b: 2
			inc: func [i /with a][b: i + either with [a][b]]
			sub: context [
				a: 3
				b: 4
				inc: func [i /with a][b: i + either with [a][b]]
			]
		]
		--assert 12 = obj10/inc 10
		--assert obj10/b = 12

		--assert 14 = obj10/sub/inc 10
		--assert obj10/sub/b = 14

	--test-- "basic-11"
		--assert 30 = obj10/inc/with 10 20
		--assert obj10/b = 30

		--assert 50 = obj10/sub/inc/with 10 40
		--assert obj10/sub/b = 50

	--test-- "basic-12"
		blk: [a: 99]
		obj12: object blk
		--assert obj12/a = 99

===end-group===

===start-group=== "Comparison tests"

	--test-- "comp-1"  --assert 	(context [])	 = (context [])
	--test-- "comp-2"  --assert not (context [a: 1]) = (context [])
	--test-- "comp-3"  --assert 	(context [a: 1]) = (context [a: 1])
	--test-- "comp-4"  --assert not (context [a: 1]) = (context [a: 2])
	--test-- "comp-5"  --assert 	(context [a: 1]) < (context [a: 2])
	--test-- "comp-6"  --assert not (context [a: 1]) >= (context [a: 2])
	--test-- "comp-7"  --assert 	(context [a: 2]) < (context [a: 1 b: none])

	--test-- "comp-8"
		obj:  context [a: 123]
		obj2: context [a: 123]
		--assert obj = obj2
		--assert not same? obj obj2
		--assert same? obj obj

===end-group===

===start-group=== "SELF test"

	--test-- "self-1"
		obj: context [
			--assert "make object! []" = mold/flat self
		]

	--test-- "self-2"
		obj: context [
			a: 123
			--assert "make object! [a: 123 b: unset]" = mold/flat self
			b: 456
		]

	--test-- "self-3"
		result: {make object! [b: 123 c: "hello" show: func [][--assert object? self] foo: unset]}

		obj: object [
			b: 123
			c: "hello"
			show: does [--assert object? self]
			--assert result = mold/flat self
			foo: does [--assert object? self c: none]
			foo
		]
		obj/show
		--assert none? obj/c

	--test-- "self-4"
		p1: object [
		    a: 1
		    b: 2
		    e: does [self/b]
		    f: does [self/b: 789 self/e]
		    --assert self/e = 2
		]
		--assert p1/e = 2
		--assert p1/f = 789

===end-group===

===start-group=== "simple object tests"

	--test-- "simple object 1"
		so1-a: 0
		so1-o: make object! [so1-a: 1]
		--assert so1-a = 0
		--assert so1-o/so1-a = 1

	--test-- "simple object 2"
		so2-s: "0"
		so2-o: make object! [so2-s: "1"]
		--assert so2-s = "0"
		--assert so2-o/so2-s = "1"

	--test-- "simple object 3"
		so3-s: "0"
		so3-i: 0
		so3-l: true
		so3-c: #"a"
		so3-b: [a b c]
		so3-f: func [][0]
		so3-bs: charset #"^(00)"
		so3-o: make object! [
			so3-s: "1"
			so3-i: 1
			so3-l: false
			so3-c: #"b"
			so3-b: [a b d]
			so3-f: func [][1]
			so3-bs: charset #"^(01)"
		]
		--assert so3-s = "0"
		--assert so3-o/so3-s = "1"
		--assert so3-i = 0
		--assert so3-o/so3-i = 1
		--assert so3-l = true
		--assert so3-o/so3-l = false
		--assert so3-c = #"a"
		--assert so3-o/so3-c = #"b"
		--assert so3-b = [a b c]
		--assert so3-o/so3-b = [a b d]
		--assert so3-f = 0
		--assert so3-o/so3-f = 1
		--assert "make bitset! #{80}" = mold so3-bs
		--assert "make bitset! #{40}" = mold so3-o/so3-bs

===end-group===

===start-group=== "nested objects"

	--test-- "no1"
		no1-o: make object! [o: make object! [i: 1] ]
		--assert no1-o/o/i = 1

	--test-- "no2"
		no2-o1: make object! [
			o2: make object! [
				i: 1
			]
		]
		--assert no2-o1/o2/i = 1

	--test-- "no3"
		no3-o1: make object! [
			o2: make object! [
			o3: make object! [
			o4: make object! [
				i: 1
			]]]
		]
		--assert no3-o1/o2/o3/o4/i = 1

	--test-- "no4"
		no4-o1: make object! [
			o2: make object! [
			o3: make object! [
			o4: make object! [
			o5: make object! [
			o6: make object! [
			o7: make object! [
				i: 1
			]]]]]]
		]
		--assert no4-o1/o2/o3/o4/o5/o6/o7/i = 1

	--test-- "no5"
		no5-o1: make object! [
			o2: make object! [
			o3: make object! [
			o4: make object! [
			o5: make object! [
			o6: make object! [
			o7: make object! [
			o8: make object! [
			o9: make object! [
			o10: make object! [
			o11: make object! [
			o12: make object! [
			o13: make object! [
			o14: make object! [
			o15: make object! [
				i: 1
			]]]]]]]]]]]]]]
		]
		--assert no5-o1/o2/o3/o4/o5/o6/o7/o8/o9/o10/o11/o12/o13/o14/o15/i = 1

	--test-- "no6 issue #928"
		no6-o: make object! [
			a: 1
			o: make object! [
				b: 2
				f: does [a]
				]
			]
		--assert 1 = no6-o/o/f

===end-group===

===start-group=== "object prototype tests"

	--test-- "op1"
		op1-o1: make object! [i: 1]
		op1-o2: make op1-o1 []
		--assert op1-o2/i = 1

	--test-- "op2"
		op2-o1: make object! [i: 1]
		op2-o2: make op2-o1 [i: 2]
		--assert op2-o2/i = 2
		--assert op2-o1/i = 1

	--test-- "op3"
		op3-o1: make object! [i: 1]
		op3-o2: make op3-o1 [i: 2 j: 3]
		--assert op3-o2/i = 2
		--assert op3-o2/j = 3

===end-group===

===start-group=== "object initialisation processing"

	--test-- "oip1"
		oip1-i: 1
		oip1-o: make object! [
			i: oip1-i
		]
		--assert 1 = oip1-o/i

	--test-- "oip2"
		oip2-i: 1
		oip2-o: make object! [
			i: either oip2-i = 1 [2] [3]
		]
		--assert 2 = oip2-o/i

	--test-- "oip3"
		oip3-i: 1
		oip3-o: make object! [
			i: 0
			set 'oip3-i 2
		]
		--assert 2 = oip3-i

	--test-- "oip4"
		oip4-o: make object! [
			i: 0
			set 'oip4-i 3
		]
		--assert 3 = oip4-i

===end-group===

===start-group=== "inheritance"

	--test-- "inherit-1"
		proto: context [
			a: 123
			get-a: does [a]
		]
		new: make proto [a: 99]
		--assert new/a = 99
		--assert new/get-a = 99
		--assert proto/a = 123
		--assert proto/get-a = 123

	--test-- "inherit-2"
		new/a: 456
		--assert new/get-a = 456
		proto/a: 759
		--assert proto/a = 759
		--assert new/get-a = 456

	--test-- "inherit-3"
		newnew: make new [
			reset: does [a: none]
		]
		--assert newnew/a = 456
		newnew/reset
		--assert none? newnew/a
		--assert new/a = 456
		--assert proto/a = 759

	--test-- "inherit-4"
		base: context [
			v: 0
			foo: does [v]
		]

		i: 0
		list: []
		loop 2 [
			bb: make base [v: i]
			--assert bb/foo = i
			append list bb
			i: i + 1
		]
		--assert object? list/1
		--assert list/1/v = 0
		--assert list/2/v = 1

	--test-- "inherit-5"
		base5: context [
			b: 123
			get-b: does [b]
			a: object [
				b: 456
				double: does [b * 2]
				set-b: func [/with v] [b: either with [v]['hello]]
			]
		]
		proto5: context [
			b: 999
			value: 71
			foo: does [b + value]
		]
		new: make base5 proto5
		--assert object? new
		--assert new/b = 999
		--assert new/value = 71
		--assert new/a/b = 456
		--assert base5/b = 123

	--test-- "inherit-6"
		--assert new/get-b = 999
		--assert new/a/double = 912
		--assert new/a/set-b/with 10
		--assert new/a/b = 10
		--assert new/b = 999
		--assert base5/b = 123
		--assert new/a/double = 20
		--assert base5/a/double = 20

	--test-- "inherit-7"
		--assert same? new/a base5/a

	--test-- "inherit-8"
		--assert new/foo = 1070

	--test-- "inherit-9"
		base9: context [
			v: 123456
			show: does [v]
		]
		i: 100
		list: []
		loop 3 [
			new9: make base9 [v: i]
			--assert new9/v = i
			--assert new9/show = i
			append list new9
			i: i + 1
		]
		--assert base9/v = 123456
		--assert list/1/v = 100
		--assert list/2/v = 101
		--assert list/3/v = 102

	--test-- "inherit-10"
		base10: make object! [
			oo: make object! [
				a: 1
			]
		]
		new10: make base10 []
		base10/oo/a: 9
		--assert 9 = new10/oo/a

	--test-- "inherit-11"
		base11: make object! [
			a: 1
			oo: make object! [
				f: func [][a]
			]
		]
		new11: make base11 [a: 2]
		--assert 1 = new11/oo/f

===end-group===

===start-group=== "external deep setting"

	--test-- "ext-1"
		p1: object [
		    a: 1
		    b: 2
		]

		p1/a: context [
			t: 99
			z: 128
			q: object [zz: 345 show: does [zz]]
		]
		--assert object? p1/a
		--assert p1/a/z = 128
		--assert p1/a/q/show = 345

	--test-- "ext-2"
		p1/a/t: does [123]
		--assert p1/a/t = 123

===end-group===

===start-group=== "dynamic invocation"

	--test-- "dyn-1"
		d: context [
			value: 998
		    f: does [value]
		]
		h: :d/f
		--assert h = 998
		d/value: 123
		--assert 123 = do [h]

	--test-- "dyn-2"
		f: func [/local z][
		    z: object [
		        a: 1
		        g: func [/with b /local c][c: 10 either with [a + b + 10][a * 2]]
		        j: func [i][i + 1]
		    ]
	    	z
		]
		o: make f [a: 3]
		--assert 46 = o/j 45
		--assert 101 = o/j 100

	--test-- "dyn-3"
		--assert 52 = o/j o/j 50

	--test-- "dyn-4"
		--assert 33 = o/g/with 20
		--assert 59 = o/g/with o/j 45

	--test-- "dyn-5"
		--assert 12 = o/j z: 5 + 6
		--assert  z = 11

	--test-- "dyn-6"
		--assert [17] = reduce [o/j o/j z: 5 + 10]
		--assert z = 15

	--test-- "dyn-7"
		repeat c 1 [
			if yes [
				--assert 52 = o/j o/j 50
				--assert 59 = o/g/with o/j 45
				--assert [22] = reduce [o/j o/j z: 5 + 15]
				--assert z = 20
			]
		]

	--test-- "dyn-8"
		o2: context [zz: none]				;-- test renaming a statically compiled object

		f: func [/alt][
			either alt [
				make object! [
					a: 10
					g: 123
				]
			][
				make object! [
					a: 1
					g: does [a]
				]
			]
		]
		o2: f
		--assert 1 = o2/g

	--test-- "dyn-9"
		o2: f/alt
		--assert 123 = o2/g

	--test-- "dyn-10"

		o: context [a: [123 789]]
		--assert if o/a [true]
		--assert if block? o/a [true]
		--assert if 123 = first o/a [true]

	--test-- "dyn-11"
		--assert either o/a [true][false]
		--assert either block? o/a [true][false]
		--assert either 789 = second o/a [true][false]

	--test-- "dyn-12"
		--assert block? all [o/a]
		--assert not 	all [false o/a]
		--assert not 	all [o/a false]
		--assert 456 = 	all [o/a 456]

	--test-- "dyn-13"
		--assert block? any [o/a 0]
		--assert block? any [false o/a]
		--assert block? any [o/a false]
		--assert block? any [o/a 456]
		--assert 654 =  any [654 o/a]

	--test-- "dyn-14"
		foreach p o/a [--assert any [p = 123 p = 789]]

	--test-- "dyn-15"
		loop length? o/a [--assert any [p = 123 p = 789]]

	--test-- "dyn-16"
		repeat c length? o/a [--assert any [c = 1 c = 2]]

	--test-- "dyn-17"
		repeat c 125 - first o/a [--assert any [c = 1 c = 2]]

	--test-- "dyn-18"
		switch/default first o/a [
			123 [
				--assert true
				switch/default second o/a [
					789 [--assert true]
				][--assert false]
			]
			789 [--assert false]
		][--assert false]

	--test-- "dyn-19"
		 --assert 0 < first o/a

	--test-- "dyn-20"
		case [
			first o/a  	[--assert true]
			'else 		[--assert false]
		]

	--test-- "dyn-21"
		case [
			0 < first o/a [--assert true]
			'else	  	  [--assert false]
		]

	--test-- "dyn-22"
		case [
			0 = first o/a 	  [--assert false]
			789 = second o/a  [--assert true]
		]

===end-group===

===start-group=== "copy"

	--test-- "copy-1"
		co1: make object! [a: 1]
		co2: copy co1
		co1/a: 2
		--assert 2 = co1/a
		--assert 1 = co2/a

	--test-- "copy-2"
		co1: make object! [
			a: 1
			f: func[][a]
		]
		co2: copy co1
		co1/a: 2
		--assert 2 = co1/f
		--assert 1 = co2/f

	--test-- "copy-3"
		co1: make object! [
			a: 1
			b: 2
			blk: [1 2 3 4]
		]
		co2: copy co1
		co1/blk/1: 5
		--assert 5 = co1/blk/1
		--assert 5 = co2/blk/1

	--test-- "copy-4"
		co1: make object! [
			a: 1
			b: 2
			blk: [1 2 3 4]
		]
		co2: copy/deep co1
		co1/blk/1: 5
		--assert 5 = co1/blk/1
		--assert 1 = co2/blk/1

	--test-- "copy-5"
		co1: make object! [
			a: 1
			s: "Silly old string"
			f: func [][
				[s a]
			]
		]
		co2: copy co1
		co1/a: 5
		co1/s/2: #"h"
		co1/s/3: #"i"
		co1/s/4: #"n"
		--assert "Shiny old string" = co1/s
		--assert "Shiny old string" = co2/s

	--test-- "copy-6"
		co1: make object! [
			a: 1
			s: "Silly old string"
		]
		co2: copy co1
		co1/a: 5
		co1/s/2: #"h"
		co1/s/3: #"i"
		co1/s/4: #"n"
		replace co1/s "old" "new"
		--assert "Shiny new string" = co1/s
		--assert "Shiny new string" = co2/s

	--test-- "copy-7"
		co5: make object! [
			a: 1
			s: "Silly old string"
		]
		co6: copy/deep co5
		co5/a: 5
		co5/s/2: #"h"
		co5/s/3: #"i"
		co5/s/4: #"n"
		replace at co5/s 7 "old" "new"
		--assert "Shiny new string" = co5/s
		--assert "Silly old string" = co6/s

	--test-- "copy-8"
		co1: make object! [
			s: "Silly old string"
			f: func[][s]
		]
		co2: copy co1
		co1/s/2: #"h"
		co1/s/3: #"i"
		co1/s/4: #"n"
		replace co1/s "old" "new"
		--assert "Shiny new string" = co1/f
		--assert "Shiny new string" = co2/f

	--test-- "copy-9"
		co1: make object! [
			s: "Silly old string"
			f: func[][s]
		]
		co2: copy/deep co1
		co1/s/2: #"h"
		co1/s/3: #"i"
		co1/s/4: #"n"
		replace co1/s "old" "new"
		--assert "Shiny new string" = co1/f
		--assert "Silly old string" = co2/f

	--test-- "copy-10"
		co1: make object! [
			a: 1
			f: func[][a]
		]
		co2: copy/deep co1
		co1/a: 2
		--assert 2 = co1/f
		--assert 1 = co2/f

	--test-- "copy-11"
		co1: make object! [
			a: 1
			oo: make object! [
				f: func[][a]
			]
		]
		co2: copy/deep co1
		co1/a: 2
		--assert 2 = co1/oo/f
		--assert 2 = co2/oo/f

	--test-- "copy-12"
		co1: make object! [
			a: 1
			oo: make object! [
				f: func[][a]
			]
		]
		co2: copy/deep co1
		co1/a: 2
		--assert 2 = co1/oo/f
		--assert 2 = co2/oo/f

===end-group===

===start-group=== "in"

	--test-- "in1"
		ino1: make object! [
			i: 1
			c: #"a"
			f: 1.0
			b: [1 2 3 4]
			s: "abcdef"
			o: make object! [
			]
		]
		--assert 'i = in ino1 'i
		--assert 'c = in ino1 'c
		--assert 'b = in ino1 'b
		--assert 'f = in ino1 'f
		--assert 's = in ino1 's
		--assert 'o = in ino1 'o

	--test-- "in2"
		ino1: make object! [
			i: 1
			c: #"a"
			f: 1.0
			b: [1 2 3 4]
			s: "abcdef"
			o: make object! [
				c: #"b"
				i: 2
				f: 2.0
				b: [5 6 7 8]
				s: "ghijkl"
				o: make object! [
				]
			]
		]
		--assert 'i = in ino1 'i
		--assert 'c = in ino1 'c
		--assert 'b = in ino1 'b
		--assert 'f = in ino1 'f
		--assert 's = in ino1 's
		--assert 'o = in ino1 'o
		--assert 'i = in ino1/o 'i
		--assert 'c = in ino1/o 'c
		--assert 'b = in ino1/o 'b
		--assert 'f = in ino1/o 'f
		--assert 's = in ino1/o 's
		--assert 'o = in ino1/o 'o

	--test-- "in3"
		ino1: make object! [
			i: 1
			c: #"a"
			f: 1.0
			b: [1 2 3 4]
			s: "abcdef"
			o: make object! [
				c: #"b"
				i: 2
				f: 2.0
				b: [5 6 7 8]
				s: "ghijkl"
				o: make object! [
					c: #"c"
					i: 3
					f: 3.0
					b: [9 10 11 12]
					s: "mnopqr"
					o: make object! [
					]
				]
			]
		]
		--assert 'i = in ino1 'i
		--assert 'c = in ino1 'c
		--assert 'b = in ino1 'b
		--assert 'f = in ino1 'f
		--assert 's = in ino1 's
		--assert 'o = in ino1 'o
		--assert 'i = in ino1/o 'i
		--assert 'c = in ino1/o 'c
		--assert 'b = in ino1/o 'b
		--assert 'f = in ino1/o 'f
		--assert 's = in ino1/o 's
		--assert 'o = in ino1/o 'o
		--assert 'i = in ino1/o/o 'i
		--assert 'c = in ino1/o/o 'c
		--assert 'b = in ino1/o/o 'b
		--assert 'f = in ino1/o/o 'f
		--assert 's = in ino1/o/o 's
		--assert 'o = in ino1/o/o 'o

		--test-- "in4"
		ino1: make object! [
			i: 1
			c: #"a"
			f: 1.0
			b: [1 2 3 4]
			s: "abcdef"
			o: make object! [
				c: #"b"
				i: 2
				f: 2.0
				b: [5 6 7 8]
				s: "ghijkl"
				o: make object! [
					c: #"c"
					i: 3
					f: 3.0
					b: [9 10 11 12]
					s: "mnopqr"
					o: make object! [
						c: #"d"
						f: 4.0
						i: 4
						b: [13 14 15 16]
						s: "stuvwx"
					]
				]
			]
		]
		--assert 'i = in ino1 'i
		--assert 'c = in ino1 'c
		--assert 'b = in ino1 'b
		--assert 'f = in ino1 'f
		--assert 's = in ino1 's
		--assert 'o = in ino1 'o
		--assert 'i = in ino1/o 'i
		--assert 'c = in ino1/o 'c
		--assert 'b = in ino1/o 'b
		--assert 'f = in ino1/o 'f
		--assert 's = in ino1/o 's
		--assert 'o = in ino1/o 'o
		--assert 'i = in ino1/o/o 'i
		--assert 'c = in ino1/o/o 'c
		--assert 'b = in ino1/o/o 'b
		--assert 'f = in ino1/o/o 'f
		--assert 's = in ino1/o/o 's
		--assert 'o = in ino1/o/o 'o
		--assert 'i = in ino1/o/o/o 'i
		--assert 'c = in ino1/o/o/o 'c
		--assert 'b = in ino1/o/o/o 'b
		--assert 'f = in ino1/o/o/o 'f
		--assert 's = in ino1/o/o/o 's

===end-group===

===start-group=== "local objects"

	f-make-obj-1: func [/local z][
	    z: object [
	        a: 1
	        g: func [/with b /local q][q: 10 either with [a + b + 10][a * 2]]
	        j: func [i][i + 1]
	    ]
		z
	]

	f-make-obj-2: func [/alt][
		either alt [
			make object! [
				a: 10
				g: 123
			]
		][
			make object! [
				a: 1
				g: does [a]
			]
		]
	]

	so3-f: func [][0]

	local-obj-fun: function [][

		--test-- "loc-basic-1"
			obj1: context []
			--assert "make object! []" = mold obj1

		--test-- "loc-basic-2"
			obj2: object []
			--assert "make object! []" = mold obj2

		--test-- "loc-basic-3"
			obj3: make object! []
			--assert "make object! []" = mold obj3

		--test-- "loc-basic-4"
			blk: []
			obj4: object blk
			--assert "make object! []" = mold obj4

		--test-- "loc-basic-5"
			obj5: object [
				a: 123
				show: does [a + 1]
				reset: does [a: none]
				--assert show = 124
				--assert a = 123
			]
			--assert obj5/show = 124
			obj5/reset
			--assert none? obj5/a

		--test-- "loc-basic-6"
			obj5/a: 456
			--assert obj5/a = 456

		--test-- "loc-basic-7"
			--assert find obj5 'a
			--assert not find obj5 'z
			--assert 456 = select obj5 'a
			--assert none? select obj5 'z

		--test-- "loc-basic-8"
			obj8: context [
				b: 123
				a: object [
					b: 456
					double: does [b * 2]
					set-b: does [b: 'hello]
				]
			]
			--assert obj8/b = 123
			--assert obj8/a/b = 456
			--assert obj8/a/double = 912
			obj8/a/set-b
			--assert obj8/a/b = 'hello

		--test-- "loc-basic-9"
			obj8/a/b: 'red
			--assert obj8/a/b = 'red

		--test-- "loc-basic-10"
			obj10: object [
				a: 1
				b: 2
				inc: func [i /with a][b: i + either with [a][b]]
				sub: context [
					a: 3
					b: 4
					inc: func [i /with a][b: i + either with [a][b]]
				]
			]
			--assert 12 = obj10/inc 10
			--assert obj10/b = 12

			--assert 14 = obj10/sub/inc 10
			--assert obj10/sub/b = 14

		--test-- "loc-basic-11"
			--assert 30 = obj10/inc/with 10 20
			--assert obj10/b = 30

			--assert 50 = obj10/sub/inc/with 10 40
			--assert obj10/sub/b = 50

		--test-- "loc-basic-12"
			blk: [a: 99]
			obj12: object blk
			--assert obj12/a = 99

		--test-- "loc-comp-1"  --assert 	(context [])	 = (context [])
		--test-- "loc-comp-2"  --assert not (context [a: 1]) = (context [])
		--test-- "loc-comp-3"  --assert 	(context [a: 1]) = (context [a: 1])
		--test-- "loc-comp-4"  --assert not (context [a: 1]) = (context [a: 2])
		--test-- "loc-comp-5"  --assert 	(context [a: 1]) < (context [a: 2])
		--test-- "loc-comp-6"  --assert not (context [a: 1]) >= (context [a: 2])
		--test-- "loc-comp-7"  --assert 	(context [a: 2]) < (context [a: 1 b: none])

		--test-- "loc-comp-8"
			obj:  context [a: 123]
			obj2: context [a: 123]
			--assert obj = obj2
			--assert not same? obj obj2
			--assert same? obj obj

		--test-- "loc-self-1"
			obj: context [
				--assert "make object! []" = mold/flat self
			]

		--test-- "loc-self-2"
			obj: context [
				a: 123
				--assert "make object! [a: 123 b: unset]" = mold/flat self
				b: 456
			]

		--test-- "loc-self-3"
			result: {make object! [b: 123 c: "hello" show: func [][--assert object? self] foo: unset]}

			obj: object [
				b: 123
				c: "hello"
				show: does [--assert object? self]
				--assert result = mold/flat self
				foo: does [--assert object? self c: none]
				foo
			]
			obj/show
			--assert none? obj/c

		--test-- "loc-self-4"
			p1: object [
			    a: 1
			    b: 2
			    e: does [self/b]
			    f: does [self/b: 789 self/e]
			    --assert self/e = 2
			]
			--assert p1/e = 2
			--assert p1/f = 789

		--test-- "loc-simple object 1"
			so1-a: 0
			so1-o: make object! [so1-a: 1]
			--assert so1-a = 0
			--assert so1-o/so1-a = 1

		--test-- "loc-simple object 2"
			so2-s: "0"
			so2-o: make object! [so2-s: "1"]
			--assert so2-s = "0"
			--assert so2-o/so2-s = "1"

		--test-- "loc-simple object 3"
			so3-s: "0"
			so3-i: 0
			so3-l: true
			so3-c: #"a"
			so3-b: [a b c]
			so3-bs: charset #"^(00)"
			so3-o: make object! [
				so3-s: "1"
				so3-i: 1
				so3-l: false
				so3-c: #"b"
				so3-b: [a b d]
				so3-f: func [][1]
				so3-bs: charset #"^(01)"
			]
			--assert so3-s = "0"
			--assert so3-o/so3-s = "1"
			--assert so3-i = 0
			--assert so3-o/so3-i = 1
			--assert so3-l = true
			--assert so3-o/so3-l = false
			--assert so3-c = #"a"
			--assert so3-o/so3-c = #"b"
			--assert so3-b = [a b c]
			--assert so3-o/so3-b = [a b d]
			--assert so3-f = 0
			--assert so3-o/so3-f = 1
			--assert "make bitset! #{80}" = mold so3-bs
			--assert "make bitset! #{40}" = mold so3-o/so3-bs

		--test-- "loc-no1"
			no1-o: make object! [o: make object! [i: 1] ]
			--assert no1-o/o/i = 1

		--test-- "loc-no2"
			no2-o1: make object! [
				o2: make object! [
					i: 1
				]
			]
			--assert no2-o1/o2/i = 1

		--test-- "loc-no3"
			no3-o1: make object! [
				o2: make object! [
				o3: make object! [
				o4: make object! [
					i: 1
				]]]
			]
			--assert no3-o1/o2/o3/o4/i = 1

		--test-- "loc-no4"
			no4-o1: make object! [
				o2: make object! [
				o3: make object! [
				o4: make object! [
				o5: make object! [
				o6: make object! [
				o7: make object! [
					i: 1
				]]]]]]
			]
			--assert no4-o1/o2/o3/o4/o5/o6/o7/i = 1

		--test-- "loc-no5"
			no5-o1: make object! [
				o2: make object! [
				o3: make object! [
				o4: make object! [
				o5: make object! [
				o6: make object! [
				o7: make object! [
				o8: make object! [
				o9: make object! [
				o10: make object! [
				o11: make object! [
				o12: make object! [
				o13: make object! [
				o14: make object! [
				o15: make object! [
					i: 1
				]]]]]]]]]]]]]]
			]
			--assert no5-o1/o2/o3/o4/o5/o6/o7/o8/o9/o10/o11/o12/o13/o14/o15/i = 1

		--test-- "loc-no6 issue #928"
			no6-o: make object! [
				a: 1
				o: make object! [
					b: 2
					f: does [a]
					]
				]
			--assert 1 = no6-o/o/f

		--test-- "loc-op1"
			op1-o1: make object! [i: 1]
			op1-o2: make op1-o1 []
			--assert op1-o2/i = 1

		--test-- "loc-op2"
			op2-o1: make object! [i: 1]
			op2-o2: make op2-o1 [i: 2]
			--assert op2-o2/i = 2
			--assert op2-o1/i = 1

		--test-- "loc-op3"
			op3-o1: make object! [i: 1]
			op3-o2: make op3-o1 [i: 2 j: 3]
			--assert op3-o2/i = 2
			--assert op3-o2/j = 3

		--test-- "loc-oip1"
			oip1-i: 1
			oip1-o: make object! [
				i: oip1-i
			]
			--assert 1 = oip1-o/i

		--test-- "loc-oip2"
			oip2-i: 1
			oip2-o: make object! [
				i: either oip2-i = 1 [2] [3]
			]
			--assert 2 = oip2-o/i

		--test-- "loc-oip3"
			oip3-i: 1
			oip3-o: make object! [
				i: 0
				set 'oip3-i 2
			]
			--assert 2 = oip3-i

		--test-- "loc-oip4"
			set 'oip4-i none
			oip4-o: make object! [
				i: 0
				set 'oip4-i 3
			]
			--assert 3 = oip4-i

		--test-- "loc-inherit-1"
			proto: context [
				a: 123
				get-a: does [a]
			]
			new: make proto [a: 99]
			--assert new/a = 99
			--assert new/get-a = 99
			--assert proto/a = 123
			--assert proto/get-a = 123

		--test-- "loc-inherit-2"
			new/a: 456
			--assert new/get-a = 456
			proto/a: 759
			--assert proto/a = 759
			--assert new/get-a = 456

		--test-- "loc-inherit-3"
			newnew: make new [
				reset: does [a: none]
			]
			--assert newnew/a = 456
			newnew/reset
			--assert none? newnew/a
			--assert new/a = 456
			--assert proto/a = 759

		--test-- "loc-inherit-4"
			base: context [
				v: 0
				foo: does [v]
			]

			i: 0
			list: []
			loop 2 [
				bb: make base [v: i]
				--assert bb/foo = i
				append list bb
				i: i + 1
			]
			--assert object? list/1
			--assert list/1/v = 0
			--assert list/2/v = 1

		--test-- "loc-inherit-5"
			base5: context [
				b: 123
				get-b: does [b]
				a: object [
					b: 456
					double: does [b * 2]
					set-b: func [/with v] [b: either with [v]['hello]]
				]
			]
			proto5: context [
				b: 999
				value: 71
				foo: does [b + value]
			]
			new: make base5 proto5
			--assert object? new
			--assert new/b = 999
			--assert new/value = 71
			--assert new/a/b = 456
			--assert base5/b = 123

		--test-- "loc-inherit-6"
			--assert new/get-b = 999
			--assert new/a/double = 912
			--assert new/a/set-b/with 10
			--assert new/a/b = 10
			--assert new/b = 999
			--assert base5/b = 123
			--assert new/a/double = 20
			--assert base5/a/double = 20

		--test-- "loc-inherit-7"
			--assert same? new/a base5/a

		--test-- "loc-inherit-8"
			--assert new/foo = 1070

		--test-- "loc-inherit-9"
			base9: context [
				v: 123456
				show: does [v]
			]
			i: 100
			list: []
			loop 3 [
				new9: make base9 [v: i]
				--assert new9/v = i
				--assert new9/show = i
				append list new9
				i: i + 1
			]
			--assert base9/v = 123456
			--assert list/1/v = 100
			--assert list/2/v = 101
			--assert list/3/v = 102

		--test-- "loc-ext-1"
			p1: object [
			    a: 1
			    b: 2
			]

			p1/a: context [
				t: 99
				z: 128
				q: object [zz: 345 show: does [zz]]
			]
			--assert object? p1/a
			--assert p1/a/z = 128
			--assert p1/a/q/show = 345

		--test-- "loc-ext-2"
			p1/a/t: does [123]
			--assert p1/a/t = 123

		--test-- "loc-dyn-1"
			d: context [
				value: 998
			    f: does [value]
			]
			;h: :d/f
			;--assert h = 998
			;d/value: 123
			;--assert 123 = do [h]

		--test-- "loc-dyn-2"

			o: make f-make-obj-1 [a: 3]
			--assert 46 = o/j 45
			--assert 101 = o/j 100

		--test-- "loc-dyn-3"
			--assert 52 = o/j o/j 50

		--test-- "loc-dyn-4"
			--assert 33 = o/g/with 20
			--assert 59 = o/g/with o/j 45

		--test-- "loc-dyn-5"
			--assert 12 = o/j z: 5 + 6
			--assert  z = 11

		--test-- "loc-dyn-6"
			--assert [17] = reduce [o/j o/j z: 5 + 10]
			--assert z = 15

		--test-- "loc-dyn-7"
			repeat c 1 [
				if yes [
					--assert 52 = o/j o/j 50
					--assert 59 = o/g/with o/j 45
					--assert [22] = reduce [o/j o/j z: 5 + 15]
					--assert z = 20
				]
			]

		--test-- "loc-dyn-8"
			o2: context [zz: none]				;-- test renaming a statically compiled object

			o2: f-make-obj-2
			--assert 1 = o2/g

		--test-- "loc-dyn-9"
			o2: f-make-obj-2/alt
			--assert 123 = o2/g

		--test-- "loc-dyn-10"

			o: context [a: [123 789]]
			--assert if o/a [true]
			--assert if block? o/a [true]
			--assert if 123 = first o/a [true]

		--test-- "loc-dyn-11"
			--assert either o/a [true][false]
			--assert either block? o/a [true][false]
			--assert either 789 = second o/a [true][false]

		--test-- "loc-dyn-12"
			--assert block? all [o/a]
			--assert not 	all [false o/a]
			--assert not 	all [o/a false]
			--assert 456 = 	all [o/a 456]

		--test-- "loc-dyn-13"
			--assert block? any [o/a 0]
			--assert block? any [false o/a]
			--assert block? any [o/a false]
			--assert block? any [o/a 456]
			--assert 654 =  any [654 o/a]

		--test-- "loc-dyn-14"
			foreach p o/a [--assert any [p = 123 p = 789]]

		--test-- "loc-dyn-15"
			loop length? o/a [--assert any [p = 123 p = 789]]

		--test-- "loc-dyn-16"
			repeat c length? o/a [--assert any [c = 1 c = 2]]

		--test-- "loc-dyn-17"
			repeat c 125 - first o/a [--assert any [c = 1 c = 2]]

		--test-- "loc-dyn-18"
			switch/default first o/a [
				123 [
					--assert true
					switch/default second o/a [
						789 [--assert true]
					][--assert false]
				]
				789 [--assert false]
			][--assert false]

		--test-- "loc-dyn-19"
			 --assert 0 < first o/a

		--test-- "loc-dyn-20"
			case [
				first o/a  	[--assert true]
				'else 		[--assert false]
			]

		--test-- "loc-dyn-21"
			case [
				0 < first o/a [--assert true]
				'else	  	  [--assert false]
			]

		--test-- "loc-dyn-22"
			case [
				0 = first o/a 	  [--assert false]
				789 = second o/a  [--assert true]
			]

		--test-- "loc-copy-1"
			co1: make object! [a: 1]
			co2: copy co1
			co1/a: 2
			--assert 2 = co1/a
			--assert 1 = co2/a

		--test-- "loc-copy-2"
			co1: make object! [
				a: 1
				f: func[][a]
			]
			co2: copy co1
			co1/a: 2
			--assert 2 = co1/f
			--assert 1 = co2/f

		--test-- "loc-copy-3"
			co1: make object! [
				a: 1
				b: 2
				blk: [1 2 3 4]
			]
			co2: copy co1
			co1/blk/1: 5
			--assert 5 = co1/blk/1
			--assert 5 = co2/blk/1

		--test-- "loc-copy-4"
			co1: make object! [
				a: 1
				b: 2
				blk: [1 2 3 4]
			]
			co2: copy/deep co1
			co1/blk/1: 5
			--assert 5 = co1/blk/1
			--assert 1 = co2/blk/1

		--test-- "loc-copy-5"
			co1: make object! [
				a: 1
				s: "Silly old string"
				f: func [][
					[s a]
				]
			]
			co2: copy co1
			co1/a: 5
			co1/s/2: #"h"
			co1/s/3: #"i"
			co1/s/4: #"n"
			--assert "Shiny old string" = co1/s
			--assert "Shiny old string" = co2/s

		--test-- "loc-copy-6"
			co1: make object! [
				a: 1
				s: "Silly old string"
			]
			co2: copy co1
			co1/a: 5
			co1/s/2: #"h"
			co1/s/3: #"i"
			co1/s/4: #"n"
			replace co1/s "old" "new"
			--assert "Shiny new string" = co1/s
			--assert "Shiny new string" = co2/s

		--test-- "loc-copy-7"
			co5: make object! [
				a: 1
				s: "Silly old string"
			]
			co6: copy/deep co5
			co5/a: 5
			co5/s/2: #"h"
			co5/s/3: #"i"
			co5/s/4: #"n"
			replace at co5/s 7 "old" "new"
			--assert "Shiny new string" = co5/s
			--assert "Silly old string" = co6/s

		--test-- "loc-copy-8"
			co1: make object! [
				s: "Silly old string"
				f: func[][s]
			]
			co2: copy co1
			co1/s/2: #"h"
			co1/s/3: #"i"
			co1/s/4: #"n"
			replace co1/s "old" "new"
			--assert "Shiny new string" = co1/f
			--assert "Shiny new string" = co2/f

		--test-- "loc-copy-9"
			co1: make object! [
				s: "Silly old string"
				f: func[][s]
			]
			co2: copy/deep co1
			co1/s/2: #"h"
			co1/s/3: #"i"
			co1/s/4: #"n"
			replace co1/s "old" "new"
			--assert "Shiny new string" = co1/f
			--assert "Silly old string" = co2/f

		--test-- "loc-copy-10"
			co1: make object! [
				a: 1
				f: func[][a]
			]
			co2: copy/deep co1
			co1/a: 2
			--assert 2 = co1/f
			--assert 1 = co2/f

		--test-- "loc-copy-11"
			co1: make object! [
				a: 1
				oo: make object! [
					f: func[][a]
				]
			]
			co2: copy/deep co1
			co1/a: 2
			--assert 2 = co1/oo/f
			--assert 2 = co2/oo/f

		--test-- "loc-copy-12"
			co1: make object! [
				a: 1
				oo: make object! [
					f: func[][a]
				]
			]
			co2: copy/deep co1
			co1/a: 2
			--assert 2 = co1/oo/f
			--assert 2 = co2/oo/f

		--test-- "loc-in1"
			ino1: make object! [
				i: 1
				c: #"a"
				f: 1.0
				b: [1 2 3 4]
				s: "abcdef"
				o: make object! [
				]
			]
			--assert 'i = in ino1 'i
			--assert 'c = in ino1 'c
			--assert 'b = in ino1 'b
			--assert 'f = in ino1 'f
			--assert 's = in ino1 's
			--assert 'o = in ino1 'o

		--test-- "loc-in2"
			ino1: make object! [
				i: 1
				c: #"a"
				f: 1.0
				b: [1 2 3 4]
				s: "abcdef"
				o: make object! [
					c: #"b"
					i: 2
					f: 2.0
					b: [5 6 7 8]
					s: "ghijkl"
					o: make object! [
					]
				]
			]
			--assert 'i = in ino1 'i
			--assert 'c = in ino1 'c
			--assert 'b = in ino1 'b
			--assert 'f = in ino1 'f
			--assert 's = in ino1 's
			--assert 'o = in ino1 'o
			--assert 'i = in ino1/o 'i
			--assert 'c = in ino1/o 'c
			--assert 'b = in ino1/o 'b
			--assert 'f = in ino1/o 'f
			--assert 's = in ino1/o 's
			--assert 'o = in ino1/o 'o

		--test-- "loc-in3"
			ino1: make object! [
				i: 1
				c: #"a"
				f: 1.0
				b: [1 2 3 4]
				s: "abcdef"
				o: make object! [
					c: #"b"
					i: 2
					f: 2.0
					b: [5 6 7 8]
					s: "ghijkl"
					o: make object! [
						c: #"c"
						i: 3
						f: 3.0
						b: [9 10 11 12]
						s: "mnopqr"
						o: make object! [
						]
					]
				]
			]
			--assert 'i = in ino1 'i
			--assert 'c = in ino1 'c
			--assert 'b = in ino1 'b
			--assert 'f = in ino1 'f
			--assert 's = in ino1 's
			--assert 'o = in ino1 'o
			--assert 'i = in ino1/o 'i
			--assert 'c = in ino1/o 'c
			--assert 'b = in ino1/o 'b
			--assert 'f = in ino1/o 'f
			--assert 's = in ino1/o 's
			--assert 'o = in ino1/o 'o
			--assert 'i = in ino1/o/o 'i
			--assert 'c = in ino1/o/o 'c
			--assert 'b = in ino1/o/o 'b
			--assert 'f = in ino1/o/o 'f
			--assert 's = in ino1/o/o 's
			--assert 'o = in ino1/o/o 'o

			--test-- "loc-in4"
			ino1: make object! [
				i: 1
				c: #"a"
				f: 1.0
				b: [1 2 3 4]
				s: "abcdef"
				o: make object! [
					c: #"b"
					i: 2
					f: 2.0
					b: [5 6 7 8]
					s: "ghijkl"
					o: make object! [
						c: #"c"
						i: 3
						f: 3.0
						b: [9 10 11 12]
						s: "mnopqr"
						o: make object! [
							c: #"d"
							f: 4.0
							i: 4
							b: [13 14 15 16]
							s: "stuvwx"
						]
					]
				]
			]
			--assert 'i = in ino1 'i
			--assert 'c = in ino1 'c
			--assert 'b = in ino1 'b
			--assert 'f = in ino1 'f
			--assert 's = in ino1 's
			--assert 'o = in ino1 'o
			--assert 'i = in ino1/o 'i
			--assert 'c = in ino1/o 'c
			--assert 'b = in ino1/o 'b
			--assert 'f = in ino1/o 'f
			--assert 's = in ino1/o 's
			--assert 'o = in ino1/o 'o
			--assert 'i = in ino1/o/o 'i
			--assert 'c = in ino1/o/o 'c
			--assert 'b = in ino1/o/o 'b
			--assert 'f = in ino1/o/o 'f
			--assert 's = in ino1/o/o 's
			--assert 'o = in ino1/o/o 'o
			--assert 'i = in ino1/o/o/o 'i
			--assert 'c = in ino1/o/o/o 'c
			--assert 'b = in ino1/o/o/o 'b
			--assert 'f = in ino1/o/o/o 'f
			--assert 's = in ino1/o/o/o 's

	]

	local-obj-fun

===end-group===

~~~end-file~~~

Red [
	Title:   "Red/System object! datatype test script"
	Author:  "Nenad Rakocevic & Peter W A Wood"
	File: 	 %object-test.red
	Version: "0.1.0"
	Tabs:	 4
	Rights:  "Copyright (C) 2011-2014 Nenad Rakocevic & Peter W A Wood. All rights reserved."
	License: "BSD-3 - https://github.com/dockimbel/Red/blob/origin/BSD-3-License.txt"
]

#include  %../../../quick-test/quick-test.red

~~~start-file~~~ "object"

===start-group=== "basic tests"

	--test-- "basic-1"
		obj1: context []
		--assert "make object! []" = mold obj1

	--test-- "basic-2"
		obj2: object []
		--assert "make object! []" = mold obj2

	--test-- "basic-3"
		obj3: make object! []
		--assert "make object! []" = mold obj3

	--test-- "basic-4"
		blk: []
		obj4: object blk
		--assert "make object! []" = mold obj4

	--test-- "basic-5"
		obj5: object [
			a: 123
			show: does [a + 1]
			reset: does [a: none]
			--assert show = 124
			--assert a = 123
		]
		--assert obj5/show = 124
		obj5/reset
		--assert none? obj5/a

	--test-- "basic-6"
		obj5/a: 456
		--assert obj5/a = 456

	--test-- "basic-7"
		--assert find obj5 'a
		--assert not find obj5 'z
		--assert 456 = select obj5 'a
		--assert none? select obj5 'z

	--test-- "basic-8"
		obj8: context [
			b: 123
			a: object [
				b: 456
				double: does [b * 2]
				set-b: does [b: 'hello]
			]
		]
		--assert obj8/b = 123
		--assert obj8/a/b = 456
		--assert obj8/a/double = 912
		obj8/a/set-b
		--assert obj8/a/b = 'hello

	--test-- "basic-9"
		obj8/a/b: 'red
		--assert obj8/a/b = 'red

	--test-- "basic-10"
		obj10: object [
			a: 1
			b: 2
			inc: func [i /with a][b: i + either with [a][b]]
			sub: context [
				a: 3
				b: 4
				inc: func [i /with a][b: i + either with [a][b]]
			]
		]
		--assert 12 = obj10/inc 10
		--assert obj10/b = 12

		--assert 14 = obj10/sub/inc 10
		--assert obj10/sub/b = 14

	--test-- "basic-11"
		--assert 30 = obj10/inc/with 10 20
		--assert obj10/b = 30

		--assert 50 = obj10/sub/inc/with 10 40
		--assert obj10/sub/b = 50

	--test-- "basic-12"
		blk: [a: 99]
		obj12: object blk
		--assert obj12/a = 99

===end-group===

===start-group=== "Comparison tests"

	--test-- "comp-1"  --assert 	(context [])	 = (context [])
	--test-- "comp-2"  --assert not (context [a: 1]) = (context [])
	--test-- "comp-3"  --assert 	(context [a: 1]) = (context [a: 1])
	--test-- "comp-4"  --assert not (context [a: 1]) = (context [a: 2])
	--test-- "comp-5"  --assert 	(context [a: 1]) < (context [a: 2])
	--test-- "comp-6"  --assert not (context [a: 1]) >= (context [a: 2])
	--test-- "comp-7"  --assert 	(context [a: 2]) < (context [a: 1 b: none])

	--test-- "comp-8"
		obj:  context [a: 123]
		obj2: context [a: 123]
		--assert obj = obj2
		--assert not same? obj obj2
		--assert same? obj obj

===end-group===

===start-group=== "SELF test"

	--test-- "self-1"
		obj: context [
			--assert "make object! []" = mold/flat self
		]

	--test-- "self-2"
		obj: context [
			a: 123
			--assert "make object! [a: 123 b: unset]" = mold/flat self
			b: 456
		]

	--test-- "self-3"
		result: {make object! [b: 123 c: "hello" show: func [][--assert object? self] foo: unset]}

		obj: object [
			b: 123
			c: "hello"
			show: does [--assert object? self]
			--assert result = mold/flat self
			foo: does [--assert object? self c: none]
			foo
		]
		obj/show
		--assert none? obj/c

	--test-- "self-4"
		p1: object [
		    a: 1
		    b: 2
		    e: does [self/b]
		    f: does [self/b: 789 self/e]
		    --assert self/e = 2
		]
		--assert p1/e = 2
		--assert p1/f = 789

===end-group===

===start-group=== "simple object tests"

	--test-- "simple object 1"
		so1-a: 0
		so1-o: make object! [so1-a: 1]
		--assert so1-a = 0
		--assert so1-o/so1-a = 1

	--test-- "simple object 2"
		so2-s: "0"
		so2-o: make object! [so2-s: "1"]
		--assert so2-s = "0"
		--assert so2-o/so2-s = "1"

	--test-- "simple object 3"
		so3-s: "0"
		so3-i: 0
		so3-l: true
		so3-c: #"a"
		so3-b: [a b c]
		so3-f: func [][0]
		so3-bs: charset #"^(00)"
		so3-o: make object! [
			so3-s: "1"
			so3-i: 1
			so3-l: false
			so3-c: #"b"
			so3-b: [a b d]
			so3-f: func [][1]
			so3-bs: charset #"^(01)"
		]
		--assert so3-s = "0"
		--assert so3-o/so3-s = "1"
		--assert so3-i = 0
		--assert so3-o/so3-i = 1
		--assert so3-l = true
		--assert so3-o/so3-l = false
		--assert so3-c = #"a"
		--assert so3-o/so3-c = #"b"
		--assert so3-b = [a b c]
		--assert so3-o/so3-b = [a b d]
		--assert so3-f = 0
		--assert so3-o/so3-f = 1
		--assert "make bitset! #{80}" = mold so3-bs
		--assert "make bitset! #{40}" = mold so3-o/so3-bs

===end-group===

===start-group=== "nested objects"

	--test-- "no1"
		no1-o: make object! [o: make object! [i: 1] ]
		--assert no1-o/o/i = 1

	--test-- "no2"
		no2-o1: make object! [
			o2: make object! [
				i: 1
			]
		]
		--assert no2-o1/o2/i = 1

	--test-- "no3"
		no3-o1: make object! [
			o2: make object! [
			o3: make object! [
			o4: make object! [
				i: 1
			]]]
		]
		--assert no3-o1/o2/o3/o4/i = 1

	--test-- "no4"
		no4-o1: make object! [
			o2: make object! [
			o3: make object! [
			o4: make object! [
			o5: make object! [
			o6: make object! [
			o7: make object! [
				i: 1
			]]]]]]
		]
		--assert no4-o1/o2/o3/o4/o5/o6/o7/i = 1

	--test-- "no5"
		no5-o1: make object! [
			o2: make object! [
			o3: make object! [
			o4: make object! [
			o5: make object! [
			o6: make object! [
			o7: make object! [
			o8: make object! [
			o9: make object! [
			o10: make object! [
			o11: make object! [
			o12: make object! [
			o13: make object! [
			o14: make object! [
			o15: make object! [
				i: 1
			]]]]]]]]]]]]]]
		]
		--assert no5-o1/o2/o3/o4/o5/o6/o7/o8/o9/o10/o11/o12/o13/o14/o15/i = 1

	--test-- "no6 issue #928"
		no6-o: make object! [
			a: 1
			o: make object! [
				b: 2
				f: does [a]
				]
			]
		--assert 1 = no6-o/o/f

===end-group===

===start-group=== "object prototype tests"

	--test-- "op1"
		op1-o1: make object! [i: 1]
		op1-o2: make op1-o1 []
		--assert op1-o2/i = 1

	--test-- "op2"
		op2-o1: make object! [i: 1]
		op2-o2: make op2-o1 [i: 2]
		--assert op2-o2/i = 2
		--assert op2-o1/i = 1

	--test-- "op3"
		op3-o1: make object! [i: 1]
		op3-o2: make op3-o1 [i: 2 j: 3]
		--assert op3-o2/i = 2
		--assert op3-o2/j = 3

===end-group===

===start-group=== "object initialisation processing"

	--test-- "oip1"
		oip1-i: 1
		oip1-o: make object! [
			i: oip1-i
		]
		--assert 1 = oip1-o/i

	--test-- "oip2"
		oip2-i: 1
		oip2-o: make object! [
			i: either oip2-i = 1 [2] [3]
		]
		--assert 2 = oip2-o/i

	--test-- "oip3"
		oip3-i: 1
		oip3-o: make object! [
			i: 0
			set 'oip3-i 2
		]
		--assert 2 = oip3-i

	--test-- "oip4"
		oip4-o: make object! [
			i: 0
			set 'oip4-i 3
		]
		--assert 3 = oip4-i

===end-group===

===start-group=== "inheritance"

	--test-- "inherit-1"
		proto: context [
			a: 123
			get-a: does [a]
		]
		new: make proto [a: 99]
		--assert new/a = 99
		--assert new/get-a = 99
		--assert proto/a = 123
		--assert proto/get-a = 123

	--test-- "inherit-2"
		new/a: 456
		--assert new/get-a = 456
		proto/a: 759
		--assert proto/a = 759
		--assert new/get-a = 456

	--test-- "inherit-3"
		newnew: make new [
			reset: does [a: none]
		]
		--assert newnew/a = 456
		newnew/reset
		--assert none? newnew/a
		--assert new/a = 456
		--assert proto/a = 759

	--test-- "inherit-4"
		base: context [
			v: 0
			foo: does [v]
		]

		i: 0
		list: []
		loop 2 [
			bb: make base [v: i]
			--assert bb/foo = i
			append list bb
			i: i + 1
		]
		--assert object? list/1
		--assert list/1/v = 0
		--assert list/2/v = 1

	--test-- "inherit-5"
		base5: context [
			b: 123
			get-b: does [b]
			a: object [
				b: 456
				double: does [b * 2]
				set-b: func [/with v] [b: either with [v]['hello]]
			]
		]
		proto5: context [
			b: 999
			value: 71
			foo: does [b + value]
		]
		new: make base5 proto5
		--assert object? new
		--assert new/b = 999
		--assert new/value = 71
		--assert new/a/b = 456
		--assert base5/b = 123

	--test-- "inherit-6"
		--assert new/get-b = 999
		--assert new/a/double = 912
		--assert new/a/set-b/with 10
		--assert new/a/b = 10
		--assert new/b = 999
		--assert base5/b = 123
		--assert new/a/double = 20
		--assert base5/a/double = 20

	--test-- "inherit-7"
		--assert same? new/a base5/a

	--test-- "inherit-8"
		--assert new/foo = 1070

	--test-- "inherit-9"
		base9: context [
			v: 123456
			show: does [v]
		]
		i: 100
		list: []
		loop 3 [
			new9: make base9 [v: i]
			--assert new9/v = i
			--assert new9/show = i
			append list new9
			i: i + 1
		]
		--assert base9/v = 123456
		--assert list/1/v = 100
		--assert list/2/v = 101
		--assert list/3/v = 102

	--test-- "inherit-10"
		base10: make object! [
			oo: make object! [
				a: 1
			]
		]
		new10: make base10 []
		base10/oo/a: 9
		--assert 9 = new10/oo/a

	--test-- "inherit-11"
		base11: make object! [
			a: 1
			oo: make object! [
				f: func [][a]
			]
		]
		new11: make base11 [a: 2]
		--assert 1 = new11/oo/f

===end-group===

===start-group=== "external deep setting"

	--test-- "ext-1"
		p1: object [
		    a: 1
		    b: 2
		]

		p1/a: context [
			t: 99
			z: 128
			q: object [zz: 345 show: does [zz]]
		]
		--assert object? p1/a
		--assert p1/a/z = 128
		--assert p1/a/q/show = 345

	--test-- "ext-2"
		p1/a/t: does [123]
		--assert p1/a/t = 123

===end-group===

===start-group=== "dynamic invocation"

	--test-- "dyn-1"
		d: context [
			value: 998
		    f: does [value]
		]
		h: :d/f
		--assert h = 998
		d/value: 123
		--assert 123 = do [h]

	--test-- "dyn-2"
		f: func [/local z][
		    z: object [
		        a: 1
		        g: func [/with b /local c][c: 10 either with [a + b + 10][a * 2]]
		        j: func [i][i + 1]
		    ]
	    	z
		]
		o: make f [a: 3]
		--assert 46 = o/j 45
		--assert 101 = o/j 100

	--test-- "dyn-3"
		--assert 52 = o/j o/j 50

	--test-- "dyn-4"
		--assert 33 = o/g/with 20
		--assert 59 = o/g/with o/j 45

	--test-- "dyn-5"
		--assert 12 = o/j z: 5 + 6
		--assert  z = 11

	--test-- "dyn-6"
		--assert [17] = reduce [o/j o/j z: 5 + 10]
		--assert z = 15

	--test-- "dyn-7"
		repeat c 1 [
			if yes [
				--assert 52 = o/j o/j 50
				--assert 59 = o/g/with o/j 45
				--assert [22] = reduce [o/j o/j z: 5 + 15]
				--assert z = 20
			]
		]

	--test-- "dyn-8"
		o2: context [zz: none]				;-- test renaming a statically compiled object

		f: func [/alt][
			either alt [
				make object! [
					a: 10
					g: 123
				]
			][
				make object! [
					a: 1
					g: does [a]
				]
			]
		]
		o2: f
		--assert 1 = o2/g

	--test-- "dyn-9"
		o2: f/alt
		--assert 123 = o2/g

===end-group===

===start-group=== "copy"

	--test-- "copy-1"
		co1: make object! [a: 1]
		co2: copy co1
		co1/a: 2
		--assert 2 = co1/a
		--assert 1 = co2/a

	--test-- "copy-2"
		co1: make object! [
			a: 1
			f: func[][a]
		]
		co2: copy co1
		co1/a: 2
		--assert 2 = co1/f
		--assert 2 = co2/f

	--test-- "copy-3"
		co1: make object! [
			a: 1
			b: 2
			blk: [1 2 3 4]
		]
		co2: copy co1
		co1/blk/1: 5
		--assert 5 = co1/blk/1
		--assert 5 = co2/blk/1

	--test-- "copy-4"
		co1: make object! [
			a: 1
			b: 2
			blk: [1 2 3 4]
		]
		co2: copy/deep co1
		co1/blk/1: 5
		--assert 5 = co1/blk/1
		--assert 1 = co2/blk/1

	--test-- "copy-5"
		co1: make object! [
			a: 1
			s: "Silly old string"
			f: func [][
				[s a]
			]
		]
		co2: copy co1
		co1/a: 5
		co1/s/2: #"h"
		co1/s/3: #"i"
		co1/s/4: #"n"
		--assert "Shiny old string" = co1/s
		--assert "Shiny old string" = co2/s

	--test-- "copy-6"
		co1: make object! [
			a: 1
			s: "Silly old string"
		]
		co2: copy co1
		co1/a: 5
		co1/s/2: #"h"
		co1/s/3: #"i"
		co1/s/4: #"n"
		replace co1/s "old" "new"
		--assert "Shiny new string" = co1/s
		--assert "Shiny new string" = co2/s

	--test-- "copy-7"
		co5: make object! [
			a: 1
			s: ["Silly old string"]
		]
		co6: copy/deep co5
		co5/a: 5
		co5/s/2: #"h"
		co5/s/3: #"i"
		co5/s/4: #"n"
		replace co5/s "old" "new"
		--assert "Shiny new string" = co5/s
		--assert "Silly old string" = co6/s

	--test-- "copy-8"
		co1: make object! [
			s: "Silly old string"
			f: func[][s]
		]
		co2: copy co1
		co1/s/2: #"h"
		co1/s/3: #"i"
		co1/s/4: #"n"
		replace co1/s "old" "new"
		--assert "Shiny new string" = co1/f
		--assert "Shiny new string" = co2/f

	--test-- "copy-9"
		co1: make object! [
			s: "Silly old string"
			f: func[][s]
		]
		co2: copy/deep co1
		co1/s/2: #"h"
		co1/s/3: #"i"
		co1/s/4: #"n"
		replace co1/s "old" "new"
		--assert "Shiny new string" = co1/f
		--assert "Silly old string" = co2/f

	--test-- "copy-10"
		co1: make object! [
			a: 1
			f: func[][a]
		]
		co2: copy/deep co1
		co1/a: 2
		--assert 2 = co1/f
		--assert 1 = co2/f

	--test-- "copy-11"
		co1: make object! [
			a: 1
			oo: make object! [
				f: func[][a]
			]
		]
		co2: copy/deep co1
		co1/a: 2
		--assert 2 = co1/oo/f
		--assert 2 = co2/oo/f

	--test-- "copy-12"
		co1: make object! [
			a: 1
			oo: make object! [
				f: func[][a]
			]
		]
		co2: copy/deep co1
		co1/a: 2
		--assert 2 = co1/oo/f
		--assert 2 = co2/oo/f

===end-group===

===start-group=== "in"

	--test-- "in1"
		ino1: make object! [
			i: 1
			c: #"a"
			f: 1.0
			b: [1 2 3 4]
			s: "abcdef"
			o: make object! [
			]
		]
		--assert 'i = in ino1 'i
		--assert 'c = in ino1 'c
		--assert 'b = in ino1 'b
		--assert 'f = in ino1 'f
		--assert 's = in ino1 's
		--assert 'o = in ino1 'o

	--test-- "in2"
		ino1: make object! [
			i: 1
			c: #"a"
			f: 1.0
			b: [1 2 3 4]
			s: "abcdef"
			o: make object! [
				c: #"b"
				i: 2
				f: 2.0
				b: [5 6 7 8]
				s: "ghijkl"
				o: make object! [
				]
			]
		]
		--assert 'i = in ino1 'i
		--assert 'c = in ino1 'c
		--assert 'b = in ino1 'b
		--assert 'f = in ino1 'f
		--assert 's = in ino1 's
		--assert 'o = in ino1 'o
		--assert 'i = in ino1/o 'i
		--assert 'c = in ino1/o 'c
		--assert 'b = in ino1/o 'b
		--assert 'f = in ino1/o 'f
		--assert 's = in ino1/o 's
		--assert 'o = in ino1/o 'o

	--test-- "in3"
		ino1: make object! [
			i: 1
			c: #"a"
			f: 1.0
			b: [1 2 3 4]
			s: "abcdef"
			o: make object! [
				c: #"b"
				i: 2
				f: 2.0
				b: [5 6 7 8]
				s: "ghijkl"
				o: make object! [
					c: #"c"
					i: 3
					f: 3.0
					b: [9 10 11 12]
					s: "mnopqr"
					o: make object! [
					]
				]
			]
		]
		--assert 'i = in ino1 'i
		--assert 'c = in ino1 'c
		--assert 'b = in ino1 'b
		--assert 'f = in ino1 'f
		--assert 's = in ino1 's
		--assert 'o = in ino1 'o
		--assert 'i = in ino1/o 'i
		--assert 'c = in ino1/o 'c
		--assert 'b = in ino1/o 'b
		--assert 'f = in ino1/o 'f
		--assert 's = in ino1/o 's
		--assert 'o = in ino1/o 'o
		--assert 'i = in ino1/o/o 'i
		--assert 'c = in ino1/o/o 'c
		--assert 'b = in ino1/o/o 'b
		--assert 'f = in ino1/o/o 'f
		--assert 's = in ino1/o/o 's
		--assert 'o = in ino1/o/o 'o

		--test-- "in4"
		ino1: make object! [
			i: 1
			c: #"a"
			f: 1.0
			b: [1 2 3 4]
			s: "abcdef"
			o: make object! [
				c: #"b"
				i: 2
				f: 2.0
				b: [5 6 7 8]
				s: "ghijkl"
				o: make object! [
					c: #"c"
					i: 3
					f: 3.0
					b: [9 10 11 12]
					s: "mnopqr"
					o: make object! [
						c: #"d"
						f: 4.0
						i: 4
						b: [13 14 15 16]
						s: "stuvwx"
					]
				]
			]
		]
		--assert 'i = in ino1 'i
		--assert 'c = in ino1 'c
		--assert 'b = in ino1 'b
		--assert 'f = in ino1 'f
		--assert 's = in ino1 's
		--assert 'o = in ino1 'o
		--assert 'i = in ino1/o 'i
		--assert 'c = in ino1/o 'c
		--assert 'b = in ino1/o 'b
		--assert 'f = in ino1/o 'f
		--assert 's = in ino1/o 's
		--assert 'o = in ino1/o 'o
		--assert 'i = in ino1/o/o 'i
		--assert 'c = in ino1/o/o 'c
		--assert 'b = in ino1/o/o 'b
		--assert 'f = in ino1/o/o 'f
		--assert 's = in ino1/o/o 's
		--assert 'o = in ino1/o/o 'o
		--assert 'i = in ino1/o/o/o 'i
		--assert 'c = in ino1/o/o/o 'c
		--assert 'b = in ino1/o/o/o 'b
		--assert 'f = in ino1/o/o/o 'f
		--assert 's = in ino1/o/o/o 's

===end-group===

===start-group=== "local objects"

	f-make-obj-1: func [/local z][
	    z: object [
	        a: 1
	        g: func [/with b /local q][q: 10 either with [a + b + 10][a * 2]]
	        j: func [i][i + 1]
	    ]
		z
	]

	f-make-obj-2: func [/alt][
		either alt [
			make object! [
				a: 10
				g: 123
			]
		][
			make object! [
				a: 1
				g: does [a]
			]
		]
	]

	so3-f: func [][0]

	local-obj-fun: function [][

		--test-- "loc-basic-1"
			obj1: context []
			--assert "make object! []" = mold obj1

		--test-- "loc-basic-2"
			obj2: object []
			--assert "make object! []" = mold obj2

		--test-- "loc-basic-3"
			obj3: make object! []
			--assert "make object! []" = mold obj3

		--test-- "loc-basic-4"
			blk: []
			obj4: object blk
			--assert "make object! []" = mold obj4

		--test-- "loc-basic-5"
			obj5: object [
				a: 123
				show: does [a + 1]
				reset: does [a: none]
				--assert show = 124
				--assert a = 123
			]
			--assert obj5/show = 124
			obj5/reset
			--assert none? obj5/a

		--test-- "loc-basic-6"
			obj5/a: 456
			--assert obj5/a = 456

		--test-- "loc-basic-7"
			--assert find obj5 'a
			--assert not find obj5 'z
			--assert 456 = select obj5 'a
			--assert none? select obj5 'z

		--test-- "loc-basic-8"
			obj8: context [
				b: 123
				a: object [
					b: 456
					double: does [b * 2]
					set-b: does [b: 'hello]
				]
			]
			--assert obj8/b = 123
			--assert obj8/a/b = 456
			--assert obj8/a/double = 912
			obj8/a/set-b
			--assert obj8/a/b = 'hello

		--test-- "loc-basic-9"
			obj8/a/b: 'red
			--assert obj8/a/b = 'red

		--test-- "loc-basic-10"
			obj10: object [
				a: 1
				b: 2
				inc: func [i /with a][b: i + either with [a][b]]
				sub: context [
					a: 3
					b: 4
					inc: func [i /with a][b: i + either with [a][b]]
				]
			]
			--assert 12 = obj10/inc 10
			--assert obj10/b = 12

			--assert 14 = obj10/sub/inc 10
			--assert obj10/sub/b = 14

		--test-- "loc-basic-11"
			--assert 30 = obj10/inc/with 10 20
			--assert obj10/b = 30

			--assert 50 = obj10/sub/inc/with 10 40
			--assert obj10/sub/b = 50

		--test-- "loc-basic-12"
			blk: [a: 99]
			obj12: object blk
			--assert obj12/a = 99

		--test-- "loc-comp-1"  --assert 	(context [])	 = (context [])
		--test-- "loc-comp-2"  --assert not (context [a: 1]) = (context [])
		--test-- "loc-comp-3"  --assert 	(context [a: 1]) = (context [a: 1])
		--test-- "loc-comp-4"  --assert not (context [a: 1]) = (context [a: 2])
		--test-- "loc-comp-5"  --assert 	(context [a: 1]) < (context [a: 2])
		--test-- "loc-comp-6"  --assert not (context [a: 1]) >= (context [a: 2])
		--test-- "loc-comp-7"  --assert 	(context [a: 2]) < (context [a: 1 b: none])

		--test-- "loc-comp-8"
			obj:  context [a: 123]
			obj2: context [a: 123]
			--assert obj = obj2
			--assert not same? obj obj2
			--assert same? obj obj

		--test-- "loc-self-1"
			obj: context [
				--assert "make object! []" = mold/flat self
			]

		--test-- "loc-self-2"
			obj: context [
				a: 123
				--assert "make object! [a: 123 b: unset]" = mold/flat self
				b: 456
			]

		--test-- "loc-self-3"
			result: {make object! [b: 123 c: "hello" show: func [][--assert object? self] foo: unset]}

			obj: object [
				b: 123
				c: "hello"
				show: does [--assert object? self]
				--assert result = mold/flat self
				foo: does [--assert object? self c: none]
				foo
			]
			obj/show
			--assert none? obj/c

		--test-- "loc-self-4"
			p1: object [
			    a: 1
			    b: 2
			    e: does [self/b]
			    f: does [self/b: 789 self/e]
			    --assert self/e = 2
			]
			--assert p1/e = 2
			--assert p1/f = 789

		--test-- "loc-simple object 1"
			so1-a: 0
			so1-o: make object! [so1-a: 1]
			--assert so1-a = 0
			--assert so1-o/so1-a = 1

		--test-- "loc-simple object 2"
			so2-s: "0"
			so2-o: make object! [so2-s: "1"]
			--assert so2-s = "0"
			--assert so2-o/so2-s = "1"

		--test-- "loc-simple object 3"
			so3-s: "0"
			so3-i: 0
			so3-l: true
			so3-c: #"a"
			so3-b: [a b c]
			so3-bs: charset #"^(00)"
			so3-o: make object! [
				so3-s: "1"
				so3-i: 1
				so3-l: false
				so3-c: #"b"
				so3-b: [a b d]
				so3-f: func [][1]
				so3-bs: charset #"^(01)"
			]
			--assert so3-s = "0"
			--assert so3-o/so3-s = "1"
			--assert so3-i = 0
			--assert so3-o/so3-i = 1
			--assert so3-l = true
			--assert so3-o/so3-l = false
			--assert so3-c = #"a"
			--assert so3-o/so3-c = #"b"
			--assert so3-b = [a b c]
			--assert so3-o/so3-b = [a b d]
			--assert so3-f = 0
			--assert so3-o/so3-f = 1
			--assert "make bitset! #{80}" = mold so3-bs
			--assert "make bitset! #{40}" = mold so3-o/so3-bs

		--test-- "loc-no1"
			no1-o: make object! [o: make object! [i: 1] ]
			--assert no1-o/o/i = 1

		--test-- "loc-no2"
			no2-o1: make object! [
				o2: make object! [
					i: 1
				]
			]
			--assert no2-o1/o2/i = 1

		--test-- "loc-no3"
			no3-o1: make object! [
				o2: make object! [
				o3: make object! [
				o4: make object! [
					i: 1
				]]]
			]
			--assert no3-o1/o2/o3/o4/i = 1

		--test-- "loc-no4"
			no4-o1: make object! [
				o2: make object! [
				o3: make object! [
				o4: make object! [
				o5: make object! [
				o6: make object! [
				o7: make object! [
					i: 1
				]]]]]]
			]
			--assert no4-o1/o2/o3/o4/o5/o6/o7/i = 1

		--test-- "loc-no5"
			no5-o1: make object! [
				o2: make object! [
				o3: make object! [
				o4: make object! [
				o5: make object! [
				o6: make object! [
				o7: make object! [
				o8: make object! [
				o9: make object! [
				o10: make object! [
				o11: make object! [
				o12: make object! [
				o13: make object! [
				o14: make object! [
				o15: make object! [
					i: 1
				]]]]]]]]]]]]]]
			]
			--assert no5-o1/o2/o3/o4/o5/o6/o7/o8/o9/o10/o11/o12/o13/o14/o15/i = 1

		--test-- "loc-no6 issue #928"
			no6-o: make object! [
				a: 1
				o: make object! [
					b: 2
					f: does [a]
					]
				]
			--assert 1 = no6-o/o/f

		--test-- "loc-op1"
			op1-o1: make object! [i: 1]
			op1-o2: make op1-o1 []
			--assert op1-o2/i = 1

		--test-- "loc-op2"
			op2-o1: make object! [i: 1]
			op2-o2: make op2-o1 [i: 2]
			--assert op2-o2/i = 2
			--assert op2-o1/i = 1

		--test-- "loc-op3"
			op3-o1: make object! [i: 1]
			op3-o2: make op3-o1 [i: 2 j: 3]
			--assert op3-o2/i = 2
			--assert op3-o2/j = 3

		--test-- "loc-oip1"
			oip1-i: 1
			oip1-o: make object! [
				i: oip1-i
			]
			--assert 1 = oip1-o/i

		--test-- "loc-oip2"
			oip2-i: 1
			oip2-o: make object! [
				i: either oip2-i = 1 [2] [3]
			]
			--assert 2 = oip2-o/i

		--test-- "loc-oip3"
			oip3-i: 1
			oip3-o: make object! [
				i: 0
				set 'oip3-i 2
			]
			--assert 2 = oip3-i

		--test-- "loc-oip4"
			set 'oip4-i none
			oip4-o: make object! [
				i: 0
				set 'oip4-i 3
			]
			--assert 3 = oip4-i

		--test-- "loc-inherit-1"
			proto: context [
				a: 123
				get-a: does [a]
			]
			new: make proto [a: 99]
			--assert new/a = 99
			--assert new/get-a = 99
			--assert proto/a = 123
			--assert proto/get-a = 123

		--test-- "loc-inherit-2"
			new/a: 456
			--assert new/get-a = 456
			proto/a: 759
			--assert proto/a = 759
			--assert new/get-a = 456

		--test-- "loc-inherit-3"
			newnew: make new [
				reset: does [a: none]
			]
			--assert newnew/a = 456
			newnew/reset
			--assert none? newnew/a
			--assert new/a = 456
			--assert proto/a = 759

		--test-- "loc-inherit-4"
			base: context [
				v: 0
				foo: does [v]
			]

			i: 0
			list: []
			loop 2 [
				bb: make base [v: i]
				--assert bb/foo = i
				append list bb
				i: i + 1
			]
			--assert object? list/1
			--assert list/1/v = 0
			--assert list/2/v = 1

		--test-- "loc-inherit-5"
			base5: context [
				b: 123
				get-b: does [b]
				a: object [
					b: 456
					double: does [b * 2]
					set-b: func [/with v] [b: either with [v]['hello]]
				]
			]
			proto5: context [
				b: 999
				value: 71
				foo: does [b + value]
			]
			new: make base5 proto5
			--assert object? new
			--assert new/b = 999
			--assert new/value = 71
			--assert new/a/b = 456
			--assert base5/b = 123

		--test-- "loc-inherit-6"
			--assert new/get-b = 999
			--assert new/a/double = 912
			--assert new/a/set-b/with 10
			--assert new/a/b = 10
			--assert new/b = 999
			--assert base5/b = 123
			--assert new/a/double = 20
			--assert base5/a/double = 20

		--test-- "loc-inherit-7"
			--assert same? new/a base5/a

		--test-- "loc-inherit-8"
			--assert new/foo = 1070

		--test-- "loc-inherit-9"
			base9: context [
				v: 123456
				show: does [v]
			]
			i: 100
			list: []
			loop 3 [
				new9: make base9 [v: i]
				--assert new9/v = i
				--assert new9/show = i
				append list new9
				i: i + 1
			]
			--assert base9/v = 123456
			--assert list/1/v = 100
			--assert list/2/v = 101
			--assert list/3/v = 102

		--test-- "loc-ext-1"
			p1: object [
			    a: 1
			    b: 2
			]

			p1/a: context [
				t: 99
				z: 128
				q: object [zz: 345 show: does [zz]]
			]
			--assert object? p1/a
			--assert p1/a/z = 128
			--assert p1/a/q/show = 345

		--test-- "loc-ext-2"
			p1/a/t: does [123]
			--assert p1/a/t = 123

		--test-- "loc-dyn-1"
			d: context [
				value: 998
			    f: does [value]
			]
			;h: :d/f
			;--assert h = 998
			;d/value: 123
			;--assert 123 = do [h]

		--test-- "loc-dyn-2"

			o: make f-make-obj-1 [a: 3]
			--assert 46 = o/j 45
			--assert 101 = o/j 100

		--test-- "loc-dyn-3"
			--assert 52 = o/j o/j 50

		--test-- "loc-dyn-4"
			--assert 33 = o/g/with 20
			--assert 59 = o/g/with o/j 45

		--test-- "loc-dyn-5"
			--assert 12 = o/j z: 5 + 6
			--assert  z = 11

		--test-- "loc-dyn-6"
			--assert [17] = reduce [o/j o/j z: 5 + 10]
			--assert z = 15

		--test-- "loc-dyn-7"
			repeat c 1 [
				if yes [
					--assert 52 = o/j o/j 50
					--assert 59 = o/g/with o/j 45
					--assert [22] = reduce [o/j o/j z: 5 + 15]
					--assert z = 20
				]
			]

		--test-- "loc-dyn-8"
			o2: context [zz: none]				;-- test renaming a statically compiled object

			o2: f-make-obj-2
			--assert 1 = o2/g

		--test-- "loc-dyn-9"
			o2: f-make-obj-2/alt
			--assert 123 = o2/g

	]

	local-obj-fun

===end-group===

~~~end-file~~~


TESTS: new math with sub-expressions tests

Red/System [
	Title:   "Red/System math mixed tests script"
	Author:  "Nenad Rakocevic"
	File: 	 %math-mixed-test.reds
	Rights:  "Copyright (C) 2011 Nenad Rakocevic. All rights reserved."
	License: "BSD-3 - https://github.com/dockimbel/Red/blob/origin/BSD-3-License.txt"
]

#include %../../quick-test/quick-test.reds

~~~start-file~~~ "math-mixed"

===start-group=== "Simple nested expressions"

	ident: func [i [integer!] return: [integer!]][i]

	a: 1
	b: 2
	c: 3

	--test-- "math-nested-1"
	--assert 1 + (3 - 2) = 2

	--test-- "math-nested-2"
	--assert a + (3 - 2) = 2

	--test-- "math-nested-3"
	--assert a + (3 - b) = 2

	--test-- "math-nested-4"
	--assert a + (c - 2) = 2

	--test-- "math-nested-5"
	--assert a + (c - b) = b

	--test-- "math-nested-6"
	--assert (3 - 1) + (3 - 2) = 3

	--test-- "math-nested-7"
	--assert (c - a) + (c - b) = c

	--test-- "math-nested-8"
	--assert ((3 - 1) - (3 - 2)) - ((3 - 1) - (3 - 2)) = 0

	--test-- "math-nested-9"
	--assert ((c - a) - (c - b)) - ((c - a) - (c - b)) = 0

	--test-- "math-nested-10"
	--assert (3 * 1) + (3 * 2) = 9

	--test-- "math-nested-11"
	--assert (3 / 1) + (3 / 2) = 4

	--test-- "math-nested-12"
	--assert ((3 * 1) - (3 * 2)) * ((3 * 1) - (3 * 2)) = 9

	--test-- "math-nested-13"
	--assert (c * a) + (c * b) = 9

	--test-- "math-nested-14"
	--assert (3 * ident 1) + (3 * ident 2) = 9

	--test-- "math-nested-15"
	--assert ((ident 3) * ident 1) + ((ident 3) * ident 2) = 9

	foo-nested: func [
		/local a b c
	][
		a: 2
		b: 3
		c: 4

		--test-- "loc-math-nested-1"
		--assert 1 + (3 - 2) = 2

		--test-- "loc-math-nested-2"
		--assert a + (3 - 2) = 3

		--test-- "loc-math-nested-3"
		--assert a + (3 - b) = 2

		--test-- "loc-math-nested-4"
		--assert a + (c - 2) = 4

		--test-- "loc-math-nested-5"
		--assert a + (c - b) = b

		--test-- "loc-math-nested-6"
		--assert (3 - 1) + (3 - 2) = 3

		--test-- "loc-math-nested-7"
		--assert (c - a) + (c - b) = b

		--test-- "loc-math-nested-8"
		--assert ((3 - 1) - (3 - 2)) - ((3 - 1) - (3 - 2)) = 0

		--test-- "loc-math-nested-9"
		--assert ((c - a) - (c - b)) - ((c - a) - (c - b)) = 0
	]
	foo-nested

===end-group===

===start-group=== "Mixed nested expressions"

	fooA: func [a [int-ptr!] return: [int-ptr!]][a]
	fooB: func [b [integer!] return: [integer!]][b]

	s: declare struct! [
		a	[int-ptr!]
		b	[integer!]
		c	[int-ptr!]
	]
	s/b: 3
	size: 2

	--test-- "math-mixed-1"
	s/a: as int-ptr! 1000h
	s/a: s/a + 2								;-- reg/imm
	--assert s/a = as int-ptr! 1008h

	--test-- "math-mixed-2"
	s/a: as int-ptr! 1000h
	i: 2 + as-integer s/a						;-- imm/reg
	--assert i = 1002h

	--test-- "math-mixed-3"
	s/a: as int-ptr! 1000h
	s/a: (as int-ptr! 2) + as-integer s/a		;-- imm/reg
	--assert s/a = as int-ptr! 4002h

	--test-- "math-mixed-4"
	s/a: as int-ptr! s/b + size					;-- reg/ref
	--assert s/a = as int-ptr! 05h

	--test-- "math-mixed-5"
	i: size + s/b								;-- ref/reg
	--assert i = 05h

	--test-- "math-mixed-6"
	s/a: as int-ptr! size + s/b					;-- ref/reg
	--assert s/a = as int-ptr! 05h

	--test-- "math-mixed-7"
	i: s/b + size - 1							;-- (reg/ref)/imm
	--assert i = 04h

	--test-- "math-mixed-8"
	i: s/b - 1 + size							;-- (reg/imm)/ref
	--assert i = 04h

	--test-- "math-mixed-9"
	s/a: as int-ptr! 1000h
	s/a: s/a + size - 1							;-- (reg/ref)/imm
	--assert s/a = as int-ptr! 1004h

	--test-- "math-mixed-10"
	s/a: as int-ptr! 1000h
	s/a: s/a - 1 + size							;-- (reg/imm)/ref
	--assert s/a = as int-ptr! 1004h

	--test-- "math-mixed-11"
	s/a: as int-ptr! 1000h
	s/c: s/a + s/b + 2							;-- (reg/reg)/imm
	--assert s/c = as int-ptr! 1014h

	--test-- "math-mixed-12"
	s/a: as int-ptr! 1000h
	s/c: s/a + s/b + size						;-- (reg/reg)/ref
	--assert s/c = as int-ptr! 1014h

	--test-- "math-mixed-13"
	s/a: as int-ptr! 1000h
	s/c: s/a + s/b + s/b						;-- (reg/reg)/reg
	--assert s/c = as int-ptr! 1018h

	--test-- "math-mixed-14"
	s/a: as int-ptr! 1000h
	s/a: (fooA s/a) + 2							;-- reg/imm
	--assert s/a = as int-ptr! 1008h

	--test-- "math-mixed-15"
	s/a: as int-ptr! 1000h
	i: 2 + as-integer fooA s/a					;-- imm/reg
	--assert i = 1002h

	--test-- "math-mixed-16"
	s/a: as int-ptr! 1000h
	s/a: (as int-ptr! 2) + as-integer fooA s/a	;-- imm/reg
	--assert s/a = as int-ptr! 4002h

	--test-- "math-mixed-17"
	s/a: (as int-ptr! fooB s/b) + size			;-- reg/ref
	--assert s/a = as int-ptr! 0Bh

	--test-- "math-mixed-18"
	i: size + fooB s/b							;-- ref/reg
	--assert i = 05h

	--test-- "math-mixed-19"
	s/a: (as int-ptr! size) + fooB s/b			;-- ref/reg
	--assert s/a = as int-ptr! 0Eh

	--test-- "math-mixed-20"
	i: (fooB s/b) + size - 1					;-- (reg/ref)/imm
	--assert i = 04h

	--test-- "math-mixed-21"
	i: (fooB s/b) - 1 + size					;-- (reg/imm)/ref
	--assert i = 04h

	--test-- "math-mixed-22"
	s/a: as int-ptr! 1000h
	s/a: (fooA s/a) + size - 1					;-- (reg/ref)/imm
	--assert s/a = as int-ptr! 1004h

	--test-- "math-mixed-23"
	s/a: as int-ptr! 1000h
	s/a: (fooA s/a) - 1 + size					;-- (reg/imm)/ref
	--assert s/a = as int-ptr! 1004h

	--test-- "math-mixed-24"
	s/a: as int-ptr! 1000h
	s/c: (fooA s/a) + s/b + 2					;-- (reg/reg)/imm
	--assert s/c = as int-ptr! 1014h

	--test-- "math-mixed-25"
	s/a: as int-ptr! 1000h
	s/c: (fooA s/a) + s/b + size				;-- (reg/reg)/ref
	--assert s/c = as int-ptr! 1014h

	--test-- "math-mixed-26"
	s/a: as int-ptr! 1000h
	s/c: (fooA s/a) + (fooB s/b) + s/b			;-- (reg/reg)/reg
	--assert s/c = as int-ptr! 1018h

	--test-- "math-mixed-27"
	s/a: as int-ptr! 1000h
	s/c: (fooA s/a) + (fooB s/b) + 2			;-- (reg/reg)/imm
	--assert s/c = as int-ptr! 1014h

	--test-- "math-mixed-28"
	s/a: as int-ptr! 1000h
	s/c: (fooA s/a) + (fooB s/b) + size			;-- (reg/reg)/ref
	--assert s/c = as int-ptr! 1014h

	--test-- "math-mixed-29"
	s/a: as int-ptr! 1000h
	s/c: (fooA s/a) + s/b + (fooB s/b) 			;-- (reg/reg)/reg
	--assert s/c = as int-ptr! 1018h

	--test-- "math-mixed-30"
	s/a: as int-ptr! 1000h
	i: s/b + (fooA s/a) + (fooB s/b) 			;-- (reg/reg)/reg
	--assert i = 1006h

	--test-- "math-mixed-31"
	s/a: as int-ptr! 1000h
	i: 2 + (fooA s/a) + (fooB s/b) 				;-- (imm/reg)/reg
	--assert i = 1005h

	--test-- "math-mixed-32"
	s/a: as int-ptr! 1000h
	i: 2 + (fooA s/a) + size					;-- (imm/reg)/ref
	--assert i = 1004h

	--test-- "math-mixed-33"
	s/a: as int-ptr! 1000h
	i: 2 + (fooA s/a) + 3						;-- (imm/reg)/imm
	--assert i = 1005h

	--test-- "math-mixed-34"
	s/a: as int-ptr! 1000h
	s/a: s/a - 2								;-- reg/imm
	--assert s/a = as int-ptr! 0FF8h

	--test-- "math-mixed-35"
	s/a: as int-ptr! 1000h
	i: 2000h - as-integer s/a					;-- imm/reg
	--assert i = 1000h

	--test-- "math-mixed-36"
	s/a: as int-ptr! 1000h
	s/a: (as int-ptr! 6000h) - as-integer s/a	;-- imm/reg
	--assert s/a = as int-ptr! 2000h

	--test-- "math-mixed-37"
	s/a: as int-ptr! s/b - size					;-- reg/ref
	--assert s/a = as int-ptr! 01h

	--test-- "math-mixed-38"
	i: size - s/b								;-- ref/reg
	--assert i = -1

	--test-- "math-mixed-39"
	s/a: (as int-ptr! size) - s/b				;-- ref/reg
	--assert s/a = as int-ptr! -10

	--test-- "math-mixed-40"
	i: s/b - size - 1							;-- (reg/ref)/imm
	--assert i = 0

	--test-- "math-mixed-41"
	i: s/b - 1 - size							;-- (reg/imm)/ref
	--assert i = 0

	--test-- "math-mixed-42"
	s/a: as int-ptr! 1000h
	s/a: s/a - size - 1							;-- (reg/ref)/imm
	--assert s/a = as int-ptr! 0FF4h

	--test-- "math-mixed-43"
	s/a: as int-ptr! 1000h
	s/a: s/a - 1 - size							;-- (reg/imm)/ref
	--assert s/a = as int-ptr! 0FF4h

	--test-- "math-mixed-44"
	s/a: as int-ptr! 1000h
	s/c: s/a - s/b - 2							;-- (reg/reg)/imm
	--assert s/c = as int-ptr! 0FECh

	--test-- "math-mixed-45"
	s/a: as int-ptr! 1000h
	s/c: s/a - s/b - size						;-- (reg/reg)/ref
	--assert s/c = as int-ptr! 0FECh

	--test-- "math-mixed-46"
	s/a: as int-ptr! 1000h
	s/c: s/a - s/b - s/b						;-- (reg/reg)/reg
	--assert s/c = as int-ptr! 0FE8h

	--test-- "math-mixed-47"
	s/a: as int-ptr! 1000h
	s/a: (fooA s/a) - 2							;-- reg/imm
	--assert s/a = as int-ptr! 0FF8h

	--test-- "math-mixed-48"
	s/a: as int-ptr! 1000h
	i: 2 - as-integer fooA s/a					;-- imm/reg
	--assert i = FFFFF002h

	--test-- "math-mixed-49"
	s/a: as int-ptr! 1000h
	s/a: (as int-ptr! 2) - as-integer fooA s/a	;-- imm/reg
	--assert s/a = as int-ptr! FFFFC002h

	--test-- "math-mixed-50"
	s/a: (as int-ptr! fooB s/b) - size			;-- reg/ref
	--assert s/a = as int-ptr! -5

	--test-- "math-mixed-51"
	i: size - fooB s/b							;-- ref/reg
	--assert i = -1

	--test-- "math-mixed-52"
	s/a: (as int-ptr! size) - fooB s/b			;-- ref/reg
	--assert s/a = as int-ptr! -10

	--test-- "math-mixed-53"
	i: (fooB s/b) - size - 1					;-- (reg/ref)/imm
	--assert i = 0

	--test-- "math-mixed-54"
	i: (fooB s/b) - 1 - size					;-- (reg/imm)/ref
	--assert i = 0

	--test-- "math-mixed-55"
	s/a: as int-ptr! 1000h
	s/a: (fooA s/a) - size - 1					;-- (reg/ref)/imm
	--assert s/a = as int-ptr! 0FF4h

	--test-- "math-mixed-56"
	s/a: as int-ptr! 1000h
	s/a: (fooA s/a) - 1 - size					;-- (reg/imm)/ref
	--assert s/a = as int-ptr! 0FF4h

	--test-- "math-mixed-57"
	s/a: as int-ptr! 1000h
	s/c: (fooA s/a) - s/b - 2					;-- (reg/reg)/imm
	--assert s/c = as int-ptr! 0FECh

	--test-- "math-mixed-58"
	s/a: as int-ptr! 1000h
	s/c: (fooA s/a) - s/b - size				;-- (reg/reg)/ref
	--assert s/c = as int-ptr! 0FECh

	--test-- "math-mixed-59"
	s/a: as int-ptr! 1000h
	s/c: (fooA s/a) - (fooB s/b) - s/b			;-- (reg/reg)/reg
	--assert s/c = as int-ptr! 0FE8h

	--test-- "math-mixed-60"
	s/a: as int-ptr! 1000h
	s/c: (fooA s/a) - (fooB s/b) - 2			;-- (reg/reg)/imm
	--assert s/c = as int-ptr! 0FECh

	--test-- "math-mixed-61"
	s/a: as int-ptr! 1000h
	s/c: (fooA s/a) - (fooB s/b) - size			;-- (reg/reg)/ref
	--assert s/c = as int-ptr! 0FECh

	--test-- "math-mixed-62"
	s/a: as int-ptr! 1000h
	s/c: (fooA s/a) - s/b - (fooB s/b) 			;-- (reg/reg)/reg
	--assert s/c = as int-ptr! 0FE8h

	--test-- "math-mixed-63"
	s/a: as int-ptr! 1000h
	i: s/b - (fooA s/a) - (fooB s/b) 			;-- (reg/reg)/reg
	--assert i = FFFFF000h

	--test-- "math-mixed-64"
	s/a: as int-ptr! 1000h
	i: 2 - (fooA s/a) - (fooB s/b) 				;-- (imm/reg)/reg
	--assert i = FFFFEFFFh

	--test-- "math-mixed-65"
	s/a: as int-ptr! 1000h
	i: 2 - (fooA s/a) - size					;-- (imm/reg)/ref
	--assert i = FFFFF000h

	--test-- "math-mixed-66"
	s/a: as int-ptr! 1000h
	i: 2 - (fooA s/a) - 3						;-- (imm/reg)/imm
	--assert i = FFFFEFFFh

	--test-- "math-mixed-67"
	s/a: as int-ptr! 1000h
	s/c: as int-ptr! 1010h
	i: as-integer s/c - s/a						;-- reg/reg (pointer - pointer)
	--assert i = 10h

	--test-- "math-mixed-68"
	s/a: as int-ptr! 1000h
	s/c: as int-ptr! 1010h
	i: as-integer (s/c - s/a) + 1				;-- reg/reg (pointer - pointer)
	--assert i = 14h

	--test-- "math-mixed-69"
	s/a: as int-ptr! 00154E28h
	s/c: as int-ptr! 00150018h
	i: (as-integer (s/a - s/c) + 1)	/ 4			;-- reg/reg (pointer - pointer)
	--assert i = 4997

	--test-- "math-mixed-70"
	p: declare struct! [
		a	[byte-ptr!]
		c	[int-ptr!]
	]
	p/a: as byte-ptr! 001F0014h
	p/c: as int-ptr!  001D0004h
	i: as-integer (p/a - ((as byte-ptr! p/c) + 16))	;-- reg/(reg/imm)
	--assert i = 00020000h

	--test-- "math-mixed-71"
	p/a: as byte-ptr! 001F0014h
	p/c: as int-ptr!  001D0014h
	series: p/c
	sz: 32
	--assert ((as byte-ptr! series) + sz) < p/a		;-- (ref/ref)/reg

===end-group===

~~~end-file~~~

Red/System [
	Title:   "Red/System math mixed tests script"
	Author:  "Nenad Rakocevic"
	File: 	 %math-mixed-test.reds
	Rights:  "Copyright (C) 2011 Nenad Rakocevic. All rights reserved."
	License: "BSD-3 - https://github.com/dockimbel/Red/blob/origin/BSD-3-License.txt"
]

#include %../../quick-test/quick-test.reds

~~~start-file~~~ "math-mixed"

===start-group=== "Simple nested expressions"

	a: 1
	b: 2
	c: 3

	--test-- "math-nested-1"
	--assert 1 + (3 - 2) = 2

	--test-- "math-nested-2"
	--assert a + (3 - 2) = 2

	--test-- "math-nested-3"
	--assert a + (3 - b) = 2

	--test-- "math-nested-4"
	--assert a + (c - 2) = 2

	--test-- "math-nested-5"
	--assert a + (c - b) = b

	--test-- "math-nested-6"
	--assert (3 - 1) + (3 - 2) = 3

	--test-- "math-nested-7"
	--assert (c - a) + (c - b) = c

	--test-- "math-nested-8"
	--assert ((3 - 1) - (3 - 2)) - ((3 - 1) - (3 - 2)) = 0

	--test-- "math-nested-9"
	--assert ((c - a) - (c - b)) - ((c - a) - (c - b)) = 0

	foo-nested: func [
		/local a b c
	][
		a: 2
		b: 3
		c: 4

		--test-- "loc-math-nested-1"
		--assert 1 + (3 - 2) = 2

		--test-- "loc-math-nested-2"
		--assert a + (3 - 2) = 3

		--test-- "loc-math-nested-3"
		--assert a + (3 - b) = 2

		--test-- "loc-math-nested-4"
		--assert a + (c - 2) = 4

		--test-- "loc-math-nested-5"
		--assert a + (c - b) = b

		--test-- "loc-math-nested-6"
		--assert (3 - 1) + (3 - 2) = 3

		--test-- "loc-math-nested-7"
		--assert (c - a) + (c - b) = b

		--test-- "loc-math-nested-8"
		--assert ((3 - 1) - (3 - 2)) - ((3 - 1) - (3 - 2)) = 0

		--test-- "loc-math-nested-9"
		--assert ((c - a) - (c - b)) - ((c - a) - (c - b)) = 0
	]
	foo-nested

===end-group===

===start-group=== "Mixed nested expressions"

	fooA: func [a [int-ptr!] return: [int-ptr!]][a]
	fooB: func [b [integer!] return: [integer!]][b]

	s: declare struct! [
		a	[int-ptr!]
		b	[integer!]
		c	[int-ptr!]
	]
	s/b: 3
	size: 2

	--test-- "math-mixed-1"
	s/a: as int-ptr! 1000h
	s/a: s/a + 2								;-- reg/imm
	--assert s/a = as int-ptr! 1008h

	--test-- "math-mixed-2"
	s/a: as int-ptr! 1000h
	i: 2 + as-integer s/a						;-- imm/reg
	--assert i = 1002h

	--test-- "math-mixed-3"
	s/a: as int-ptr! 1000h
	s/a: (as int-ptr! 2) + as-integer s/a		;-- imm/reg
	--assert s/a = as int-ptr! 4002h

	--test-- "math-mixed-4"
	s/a: as int-ptr! s/b + size					;-- reg/ref
	--assert s/a = as int-ptr! 05h

	--test-- "math-mixed-5"
	i: size + s/b								;-- ref/reg
	--assert i = 05h

	--test-- "math-mixed-6"
	s/a: as int-ptr! size + s/b					;-- ref/reg
	--assert s/a = as int-ptr! 05h

	--test-- "math-mixed-7"
	i: s/b + size - 1							;-- (reg/ref)/imm
	--assert i = 04h

	--test-- "math-mixed-8"
	i: s/b - 1 + size							;-- (reg/imm)/ref
	--assert i = 04h

	--test-- "math-mixed-9"
	s/a: as int-ptr! 1000h
	s/a: s/a + size - 1							;-- (reg/ref)/imm
	--assert s/a = as int-ptr! 1004h

	--test-- "math-mixed-10"
	s/a: as int-ptr! 1000h
	s/a: s/a - 1 + size							;-- (reg/imm)/ref
	--assert s/a = as int-ptr! 1004h

	--test-- "math-mixed-11"
	s/a: as int-ptr! 1000h
	s/c: s/a + s/b + 2							;-- (reg/reg)/imm
	--assert s/c = as int-ptr! 1014h

	--test-- "math-mixed-12"
	s/a: as int-ptr! 1000h
	s/c: s/a + s/b + size						;-- (reg/reg)/ref
	--assert s/c = as int-ptr! 1014h

	--test-- "math-mixed-13"
	s/a: as int-ptr! 1000h
	s/c: s/a + s/b + s/b						;-- (reg/reg)/reg
	--assert s/c = as int-ptr! 1018h

	--test-- "math-mixed-14"
	s/a: as int-ptr! 1000h
	s/a: (fooA s/a) + 2							;-- reg/imm
	--assert s/a = as int-ptr! 1008h

	--test-- "math-mixed-15"
	s/a: as int-ptr! 1000h
	i: 2 + as-integer fooA s/a					;-- imm/reg
	--assert i = 1002h

	--test-- "math-mixed-16"
	s/a: as int-ptr! 1000h
	s/a: (as int-ptr! 2) + as-integer fooA s/a	;-- imm/reg
	--assert s/a = as int-ptr! 4002h

	--test-- "math-mixed-17"
	s/a: (as int-ptr! fooB s/b) + size			;-- reg/ref
	--assert s/a = as int-ptr! 0Bh

	--test-- "math-mixed-18"
	i: size + fooB s/b							;-- ref/reg
	--assert i = 05h

	--test-- "math-mixed-19"
	s/a: (as int-ptr! size) + fooB s/b			;-- ref/reg
	--assert s/a = as int-ptr! 0Eh

	--test-- "math-mixed-20"
	i: (fooB s/b) + size - 1					;-- (reg/ref)/imm
	--assert i = 04h

	--test-- "math-mixed-21"
	i: (fooB s/b) - 1 + size					;-- (reg/imm)/ref
	--assert i = 04h

	--test-- "math-mixed-22"
	s/a: as int-ptr! 1000h
	s/a: (fooA s/a) + size - 1					;-- (reg/ref)/imm
	--assert s/a = as int-ptr! 1004h

	--test-- "math-mixed-23"
	s/a: as int-ptr! 1000h
	s/a: (fooA s/a) - 1 + size					;-- (reg/imm)/ref
	--assert s/a = as int-ptr! 1004h

	--test-- "math-mixed-24"
	s/a: as int-ptr! 1000h
	s/c: (fooA s/a) + s/b + 2					;-- (reg/reg)/imm
	--assert s/c = as int-ptr! 1014h

	--test-- "math-mixed-25"
	s/a: as int-ptr! 1000h
	s/c: (fooA s/a) + s/b + size				;-- (reg/reg)/ref
	--assert s/c = as int-ptr! 1014h

	--test-- "math-mixed-26"
	s/a: as int-ptr! 1000h
	s/c: (fooA s/a) + (fooB s/b) + s/b			;-- (reg/reg)/reg
	--assert s/c = as int-ptr! 1018h

	--test-- "math-mixed-27"
	s/a: as int-ptr! 1000h
	s/c: (fooA s/a) + (fooB s/b) + 2			;-- (reg/reg)/imm
	--assert s/c = as int-ptr! 1014h

	--test-- "math-mixed-28"
	s/a: as int-ptr! 1000h
	s/c: (fooA s/a) + (fooB s/b) + size			;-- (reg/reg)/ref
	--assert s/c = as int-ptr! 1014h

	--test-- "math-mixed-29"
	s/a: as int-ptr! 1000h
	s/c: (fooA s/a) + s/b + (fooB s/b) 			;-- (reg/reg)/reg
	--assert s/c = as int-ptr! 1018h

	--test-- "math-mixed-30"
	s/a: as int-ptr! 1000h
	i: s/b + (fooA s/a) + (fooB s/b) 			;-- (reg/reg)/reg
	--assert i = 1006h

	--test-- "math-mixed-31"
	s/a: as int-ptr! 1000h
	i: 2 + (fooA s/a) + (fooB s/b) 				;-- (imm/reg)/reg
	--assert i = 1005h

	--test-- "math-mixed-32"
	s/a: as int-ptr! 1000h
	i: 2 + (fooA s/a) + size					;-- (imm/reg)/ref
	--assert i = 1004h

	--test-- "math-mixed-33"
	s/a: as int-ptr! 1000h
	i: 2 + (fooA s/a) + 3						;-- (imm/reg)/imm
	--assert i = 1005h

	--test-- "math-mixed-34"
	s/a: as int-ptr! 1000h
	s/a: s/a - 2								;-- reg/imm
	--assert s/a = as int-ptr! 0FF8h

	--test-- "math-mixed-35"
	s/a: as int-ptr! 1000h
	i: 2000h - as-integer s/a					;-- imm/reg
	--assert i = 1000h

	--test-- "math-mixed-36"
	s/a: as int-ptr! 1000h
	s/a: (as int-ptr! 6000h) - as-integer s/a	;-- imm/reg
	--assert s/a = as int-ptr! 2000h

	--test-- "math-mixed-37"
	s/a: as int-ptr! s/b - size					;-- reg/ref
	--assert s/a = as int-ptr! 01h

	--test-- "math-mixed-38"
	i: size - s/b								;-- ref/reg
	--assert i = -1

	--test-- "math-mixed-39"
	s/a: (as int-ptr! size) - s/b				;-- ref/reg
	--assert s/a = as int-ptr! -10

	--test-- "math-mixed-40"
	i: s/b - size - 1							;-- (reg/ref)/imm
	--assert i = 0

	--test-- "math-mixed-41"
	i: s/b - 1 - size							;-- (reg/imm)/ref
	--assert i = 0

	--test-- "math-mixed-42"
	s/a: as int-ptr! 1000h
	s/a: s/a - size - 1							;-- (reg/ref)/imm
	--assert s/a = as int-ptr! 0FF4h

	--test-- "math-mixed-43"
	s/a: as int-ptr! 1000h
	s/a: s/a - 1 - size							;-- (reg/imm)/ref
	--assert s/a = as int-ptr! 0FF4h

	--test-- "math-mixed-44"
	s/a: as int-ptr! 1000h
	s/c: s/a - s/b - 2							;-- (reg/reg)/imm
	--assert s/c = as int-ptr! 0FECh

	--test-- "math-mixed-45"
	s/a: as int-ptr! 1000h
	s/c: s/a - s/b - size						;-- (reg/reg)/ref
	--assert s/c = as int-ptr! 0FECh

	--test-- "math-mixed-46"
	s/a: as int-ptr! 1000h
	s/c: s/a - s/b - s/b						;-- (reg/reg)/reg
	--assert s/c = as int-ptr! 0FE8h

	--test-- "math-mixed-47"
	s/a: as int-ptr! 1000h
	s/a: (fooA s/a) - 2							;-- reg/imm
	--assert s/a = as int-ptr! 0FF8h

	--test-- "math-mixed-48"
	s/a: as int-ptr! 1000h
	i: 2 - as-integer fooA s/a					;-- imm/reg
	--assert i = FFFFF002h

	--test-- "math-mixed-49"
	s/a: as int-ptr! 1000h
	s/a: (as int-ptr! 2) - as-integer fooA s/a	;-- imm/reg
	--assert s/a = as int-ptr! FFFFC002h

	--test-- "math-mixed-50"
	s/a: (as int-ptr! fooB s/b) - size			;-- reg/ref
	--assert s/a = as int-ptr! -5

	--test-- "math-mixed-51"
	i: size - fooB s/b							;-- ref/reg
	--assert i = -1

	--test-- "math-mixed-52"
	s/a: (as int-ptr! size) - fooB s/b			;-- ref/reg
	--assert s/a = as int-ptr! -10

	--test-- "math-mixed-53"
	i: (fooB s/b) - size - 1					;-- (reg/ref)/imm
	--assert i = 0

	--test-- "math-mixed-54"
	i: (fooB s/b) - 1 - size					;-- (reg/imm)/ref
	--assert i = 0

	--test-- "math-mixed-55"
	s/a: as int-ptr! 1000h
	s/a: (fooA s/a) - size - 1					;-- (reg/ref)/imm
	--assert s/a = as int-ptr! 0FF4h

	--test-- "math-mixed-56"
	s/a: as int-ptr! 1000h
	s/a: (fooA s/a) - 1 - size					;-- (reg/imm)/ref
	--assert s/a = as int-ptr! 0FF4h

	--test-- "math-mixed-57"
	s/a: as int-ptr! 1000h
	s/c: (fooA s/a) - s/b - 2					;-- (reg/reg)/imm
	--assert s/c = as int-ptr! 0FECh

	--test-- "math-mixed-58"
	s/a: as int-ptr! 1000h
	s/c: (fooA s/a) - s/b - size				;-- (reg/reg)/ref
	--assert s/c = as int-ptr! 0FECh

	--test-- "math-mixed-59"
	s/a: as int-ptr! 1000h
	s/c: (fooA s/a) - (fooB s/b) - s/b			;-- (reg/reg)/reg
	--assert s/c = as int-ptr! 0FE8h

	--test-- "math-mixed-60"
	s/a: as int-ptr! 1000h
	s/c: (fooA s/a) - (fooB s/b) - 2			;-- (reg/reg)/imm
	--assert s/c = as int-ptr! 0FECh

	--test-- "math-mixed-61"
	s/a: as int-ptr! 1000h
	s/c: (fooA s/a) - (fooB s/b) - size			;-- (reg/reg)/ref
	--assert s/c = as int-ptr! 0FECh

	--test-- "math-mixed-62"
	s/a: as int-ptr! 1000h
	s/c: (fooA s/a) - s/b - (fooB s/b) 			;-- (reg/reg)/reg
	--assert s/c = as int-ptr! 0FE8h

	--test-- "math-mixed-63"
	s/a: as int-ptr! 1000h
	i: s/b - (fooA s/a) - (fooB s/b) 			;-- (reg/reg)/reg
	--assert i = FFFFF000h

	--test-- "math-mixed-64"
	s/a: as int-ptr! 1000h
	i: 2 - (fooA s/a) - (fooB s/b) 				;-- (imm/reg)/reg
	--assert i = FFFFEFFFh

	--test-- "math-mixed-65"
	s/a: as int-ptr! 1000h
	i: 2 - (fooA s/a) - size					;-- (imm/reg)/ref
	--assert i = FFFFF000h

	--test-- "math-mixed-66"
	s/a: as int-ptr! 1000h
	i: 2 - (fooA s/a) - 3						;-- (imm/reg)/imm
	--assert i = FFFFEFFFh

	--test-- "math-mixed-67"
	s/a: as int-ptr! 1000h
	s/c: as int-ptr! 1010h
	i: as-integer s/c - s/a						;-- reg/reg (pointer - pointer)
	--assert i = 10h

	--test-- "math-mixed-68"
	s/a: as int-ptr! 1000h
	s/c: as int-ptr! 1010h
	i: as-integer (s/c - s/a) + 1				;-- reg/reg (pointer - pointer)
	--assert i = 14h

	--test-- "math-mixed-69"
	s/a: as int-ptr! 00154E28h
	s/c: as int-ptr! 00150018h
	i: (as-integer (s/a - s/c) + 1)	/ 4			;-- reg/reg (pointer - pointer)
	--assert i = 4997

	--test-- "math-mixed-70"
	p: declare struct! [
		a	[byte-ptr!]
		c	[int-ptr!]
	]
	p/a: as byte-ptr! 001F0014h
	p/c: as int-ptr!  001D0004h
	i: as-integer (p/a - ((as byte-ptr! p/c) + 16))	;-- reg/(reg/imm)
	--assert i = 00020000h

	--test-- "math-mixed-71"
	p/a: as byte-ptr! 001F0014h
	p/c: as int-ptr!  001D0014h
	series: p/c
	sz: 32
	--assert ((as byte-ptr! series) + sz) < p/a		;-- (ref/ref)/reg

===end-group===

~~~end-file~~~


TESTS: added debug prints to unicode-test.reds

Red/System [
	Title:   "Red/System runtime tools test"
	Author:  "Nenad Rakocevic & Peter W A Wood"
	File: 	 %unicode-test.reds
	Rights:  "Copyright (C) 2012 Nenad Rakocevic & Peter W A Wood. All rights reserved."
	License: "BSD-3 - https://github.com/dockimbel/Red/blob/origin/BSD-3-License.txt"
]

#include %../../../../quick-test/quick-test.reds
#include %../../../runtime/red.reds

~~~start-file~~~ "unicode"

===start-group=== "load-utf8 iso-8559 only"

with red [
  lui-func: func [
    utf8-str        [c-string!]
    return:         [c-string!]
    /local
      n             [node!]
      s             [series!]
      str           [c-string!]
  ][

    n: unicode/load-utf8 utf8-str size? utf8-str
    s: as series! n/value
    str: as c-string! s/offset
    str
  ]
]

--test-- "lui1"
  lius1:  lui-func "a"
--assert lius1/1 = #"a"

--test-- "lui2"
lius2:  lui-func "^(01)a^(7F)"
--assert lius2/1 = #"^(01)"
--assert lius2/2 = #"a"
--assert lius2/3 = #"^(7F)"

--test-- "lui3"
lius3:  lui-func "^(01)a^(7F)^(C2)^(80)^(C3)^(BF)"
--assert lius3/1 = #"^(01)"
--assert lius3/2 = #"a"
--assert lius3/3 = #"^(7F)"
--assert lius3/4 = #"^(80)"
--assert lius3/5 = #"^(FF)"

===end-group===

===start-group=== "load-utf8 UCS-2 only"
--test-- "luu21"
luu21:  lui-func "^(C4)^(80)^(C4)^(BF)^(C5)^(80)^(C5)^(BF)"
--assert luu21/1 = #"^(00)"
--assert luu21/2 = #"^(01)"
--assert luu21/3 = #"^(3F)"
--assert luu21/4 = #"^(01)"
--assert luu21/5 = #"^(40)"
--assert luu21/6 = #"^(01)"
--assert luu21/7 = #"^(7F)"
--assert luu21/8 = #"^(01)"

--test-- "luu22"
luu22:  lui-func "^(EF)^(BF)^(BF)^(DF)^(BF)^(E0)^(A0)^(80)"
--assert luu22/1 = #"^(FF)"
--assert luu22/2 = #"^(FF)"
--assert luu22/3 = #"^(FF)"
--assert luu22/4 = #"^(07)"
--assert luu22/5 = #"^(00)"
--assert luu22/6 = #"^(08)"

===end-group===

===start-group=== "load-utf8 UCS-4 only"
--test-- "luu41"
luu41:  lui-func "^(F0)^(90)^(80)^(80)"
--assert luu41/1 = #"^(00)"
--assert luu41/2 = #"^(00)"
--assert luu41/3 = #"^(01)"
--assert luu41/4 = #"^(00)"

--test-- "luu42"
luu42: lui-func "^(F4)^(8F)^(BF)^(BF)"
print [{load utf-8 F48FBFBF} lf]
print "first byte of first char! expected FF "
prin-hex as integer! luu42/1
print lf
print "second byte of first char! expected FF "
prin-hex as integer! luu42/2
print lf
print "third byte of first char! expected 10 "
prin-hex as integer! luu42/3
print lf
print "fourth byte of first char! expected 00 "
prin-hex as integer! luu42/4
print lf

--assert luu42/1 = #"^(FF)"
--assert luu42/2 = #"^(FF)"
--assert luu42/3 = #"^(10)"
--assert luu42/4 = #"^(00)"

--test-- "luu43"
luu43: lui-func "^(F0)^(90)^(80)^(80)^(F4)^(8F)^(BF)^(BF)"
print [{load utf-8 F0908080F48FBFBF} lf]
print "first byte of first char! expected 00 "
prin-hex as integer! luu43/1
print lf
print "second byte of first char! expected 00 "
prin-hex as integer! luu43/2
print lf
print "third byte of first char! expected 10 "
prin-hex as integer! luu43/3
print lf
print "fourth byte of first char! expected 00 "
prin-hex as integer! luu43/4
print lf
print "first byte of first char! expected FF "
prin-hex as integer! luu43/5
print lf
print "second byte of first char! expected FF "
prin-hex as integer! luu43/6
print lf
print "third byte of first char! expected 10 "
prin-hex as integer! luu43/7
print lf
print "fourth byte of first char! expected 00 "
prin-hex as integer! luu43/8
print lf

--assert luu43/1 = #"^(00)"
--assert luu43/2 = #"^(00)"
--assert luu43/3 = #"^(01)"
--assert luu43/4 = #"^(00)"
--assert luu43/5 = #"^(FF)"
--assert luu43/6 = #"^(FF)"
--assert luu43/7 = #"^(10)"
--assert luu43/8 = #"^(00)"

--test-- "luu44"
luu44: lui-func "^(F4)^(80)^(80)^(80)"
--assert luu44/1 = #"^(00)"
--assert luu44/2 = #"^(00)"
--assert luu44/3 = #"^(10)"
--assert luu44/4 = #"^(00)"

===end-group===

===start-group=== "load-utf8 ISO-8859 -> UCS2"
--test-- "luiu21"
luiu21: lui-func "a^(EF)^(BF)^(BF)"
--assert luiu21/1 = #"^(61)"
--assert luiu21/2 = #"^(00)"
--assert luiu21/3 = #"^(FF)"
--assert luiu21/4 = #"^(FF)"
===end-group===

===start-group=== "load-utf8 ISO-8859 -> UCS4"
--test-- "luiu41"
luiu41: lui-func "a^(F4)^(80)^(80)^(80)"
--assert luiu41/1 = #"^(61)"
--assert luiu41/2 = #"^(00)"
--assert luiu41/3 = #"^(00)"
--assert luiu41/4 = #"^(00)"
--assert luiu41/5 = #"^(00)"
--assert luiu41/6 = #"^(00)"
--assert luiu41/7 = #"^(10)"
--assert luiu41/8 = #"^(00)"
===end-group===

===start-group=== "load-utf8 ISO-8859 -> UCS2 -> UCS4"
--test-- "luiu241"
luiu241: lui-func "a^(EF)^(BF)^(BF)^(F4)^(80)^(80)^(80)"
--assert luiu241/1  = #"^(61)"
--assert luiu241/2  = #"^(00)"
--assert luiu241/3  = #"^(00)"
--assert luiu241/4  = #"^(00)"
--assert luiu241/5  = #"^(FF)"
--assert luiu241/6  = #"^(FF)"
--assert luiu241/7  = #"^(00)"
--assert luiu241/8  = #"^(00)"
--assert luiu241/9  = #"^(00)"
--assert luiu241/10 = #"^(00)"
--assert luiu241/11 = #"^(10)"
--assert luiu241/12 = #"^(00)"
===end-group===

~~~end-file~~~

Red/System [
	Title:   "Red/System runtime tools test"
	Author:  "Nenad Rakocevic & Peter W A Wood"
	File: 	 %unicode-test.reds
	Rights:  "Copyright (C) 2012 Nenad Rakocevic & Peter W A Wood. All rights reserved."
	License: "BSD-3 - https://github.com/dockimbel/Red/blob/origin/BSD-3-License.txt"
]

#include %../../../../quick-test/quick-test.reds
#include %../../../runtime/red.reds

~~~start-file~~~ "unicode"

===start-group=== "load-utf8 iso-8559 only"

with red [
  lui-func: func [
    utf8-str        [c-string!]
    return:         [c-string!]
    /local
      n             [node!]
      s             [series!]
      str           [c-string!]
  ][

    n: unicode/load-utf8 utf8-str size? utf8-str
    s: as series! n/value
    str: as c-string! s/offset
    str
  ]
]

--test-- "lui1"
  lius1:  lui-func "a"
--assert lius1/1 = #"a"

--test-- "lui2"
lius2:  lui-func "^(01)a^(7F)"
--assert lius2/1 = #"^(01)"
--assert lius2/2 = #"a"
--assert lius2/3 = #"^(7F)"

--test-- "lui3"
lius3:  lui-func "^(01)a^(7F)^(C2)^(80)^(C3)^(BF)"
--assert lius3/1 = #"^(01)"
--assert lius3/2 = #"a"
--assert lius3/3 = #"^(7F)"
--assert lius3/4 = #"^(80)"
--assert lius3/5 = #"^(FF)"

===end-group===

===start-group=== "load-utf8 UCS-2 only"
--test-- "luu21"
luu21:  lui-func "^(C4)^(80)^(C4)^(BF)^(C5)^(80)^(C5)^(BF)"
--assert luu21/1 = #"^(00)"
--assert luu21/2 = #"^(01)"
--assert luu21/3 = #"^(3F)"
--assert luu21/4 = #"^(01)"
--assert luu21/5 = #"^(40)"
--assert luu21/6 = #"^(01)"
--assert luu21/7 = #"^(7F)"
--assert luu21/8 = #"^(01)"

--test-- "luu22"
luu22:  lui-func "^(EF)^(BF)^(BF)^(DF)^(BF)^(E0)^(A0)^(80)"
--assert luu22/1 = #"^(FF)"
--assert luu22/2 = #"^(FF)"
--assert luu22/3 = #"^(FF)"
--assert luu22/4 = #"^(07)"
--assert luu22/5 = #"^(00)"
--assert luu22/6 = #"^(08)"

===end-group===

===start-group=== "load-utf8 UCS-4 only"
--test-- "luu41"
luu41:  lui-func "^(F0)^(90)^(80)^(80)"
--assert luu41/1 = #"^(00)"
--assert luu41/2 = #"^(00)"
--assert luu41/3 = #"^(01)"
--assert luu41/4 = #"^(00)"

--test-- "luu42"
luu42:  lui-func "^(F4)^(8F)^(BF)^(BF)"
--assert luu42/1 = #"^(FF)"
--assert luu42/2 = #"^(FF)"
--assert luu42/3 = #"^(10)"
--assert luu42/4 = #"^(00)"

--test-- "luu43"
luu43: lui-func "^(F0)^(90)^(80)^(80)^(F4)^(8F)^(BF)^(BF)"
--assert luu43/1 = #"^(00)"
--assert luu43/2 = #"^(00)"
--assert luu43/3 = #"^(01)"
--assert luu43/4 = #"^(00)"
--assert luu43/5 = #"^(FF)"
--assert luu43/6 = #"^(FF)"
--assert luu43/7 = #"^(10)"
--assert luu43/8 = #"^(00)"

--test-- "luu44"
luu44: lui-func "^(F4)^(80)^(80)^(80)"
--assert luu44/1 = #"^(00)"
--assert luu44/2 = #"^(00)"
--assert luu44/3 = #"^(10)"
--assert luu44/4 = #"^(00)"

===end-group===

===start-group=== "load-utf8 ISO-8859 -> UCS2"
--test-- "luiu21"
luiu21: lui-func "a^(EF)^(BF)^(BF)"
--assert luiu21/1 = #"^(61)"
--assert luiu21/2 = #"^(00)"
--assert luiu21/3 = #"^(FF)"
--assert luiu21/4 = #"^(FF)"
===end-group===

===start-group=== "load-utf8 ISO-8859 -> UCS4"
--test-- "luiu41"
luiu41: lui-func "a^(F4)^(80)^(80)^(80)"
--assert luiu41/1 = #"^(61)"
--assert luiu41/2 = #"^(00)"
--assert luiu41/3 = #"^(00)"
--assert luiu41/4 = #"^(00)"
--assert luiu41/5 = #"^(00)"
--assert luiu41/6 = #"^(00)"
--assert luiu41/7 = #"^(10)"
--assert luiu41/8 = #"^(00)"
===end-group===

===start-group=== "load-utf8 ISO-8859 -> UCS2 -> UCS4"
--test-- "luiu241"
luiu241: lui-func "a^(EF)^(BF)^(BF)^(F4)^(80)^(80)^(80)"
--assert luiu241/1  = #"^(61)"
--assert luiu241/2  = #"^(00)"
--assert luiu241/3  = #"^(00)"
--assert luiu241/4  = #"^(00)"
--assert luiu241/5  = #"^(FF)"
--assert luiu241/6  = #"^(FF)"
--assert luiu241/7  = #"^(00)"
--assert luiu241/8  = #"^(00)"
--assert luiu241/9  = #"^(00)"
--assert luiu241/10 = #"^(00)"
--assert luiu241/11 = #"^(10)"
--assert luiu241/12 = #"^(00)"
===end-group===

~~~end-file~~~