bool true = 0 == 0;
bool false = 0 <> 0;

class Object
	begin
		static
			Class classType = new Class.init( null, "Object" );
		instance
			Class getClass()
				begin
					return classType;
				end
			[]char toString()
				begin
					return "" + this;
				end
			bool equals( Object other; )
				begin
					return this == other;
				end
	end
	
class Class extends Object
	begin
		
		static
			Class classType = new Class.init( Object.classType, "Class" );
		
		instance
			Class superclass;
			[]char name;
			
			Class getClass()
				begin
					return classType;
				end

			Class getSuperclass()
				begin
					return superclass;
				end
			
			[]char getName()
				begin
					return name;
				end
			
			bool isInstance( Object object; )	
				begin
					Class objectClass;
					for 
						objectClass = object.getClass(); 
						objectClass <> null; 
						objectClass = objectClass.getSuperclass()
					do
						if objectClass == this then
							return true;
						end
					end
					return false;
				end
		
			Class init( Class superclass; []char name; )
				begin
					this.superclass = superclass;
					this.name = name;
					return this;
				end
	end
	
class A extends Object
	begin
		static
			Class classType = new Class.init( Object.classType, "A" );
			println( "execute A static" );
			int count = 0;
			[]char AStatic = "AStatic";
			[]char overrideStatic = "AOverrideStatic";
			[]char AStaticFn()
				begin
					return "AStaticFn";
				end
			[]char overrideStaticFn()
				begin
					return "AOverrideStaticFn";
				end
		instance
			Class getClass()
				begin
					return classType;
				end
			println( "execute A instance" );
			[]char AInstance = "AInstance";
			[]char overrideInstance = "AOverrideInstance";
			[]char AInstanceFn()
				begin
					return "AInstanceFn";
				end
			[]char overrideInstanceFn()
				begin
					return "AOverrideInstanceFn";
				end
			println( "Create A instance " + count );
			count = count + 1;
	end
class B extends A
	begin
		static
			Class classType = new Class.init( A.classType, "B" );
			println( "execute B static" );
			int count = 0;
			[]char BStatic = "BStatic";
			[]char overrideStatic = "BOverrideStatic";
			[]char BStaticFn()
				begin
					return "BStaticFn";
				end
			[]char overrideStaticFn()
				begin
					return "BOverrideStaticFn";
				end
		instance
			Class getClass()
				begin
					return classType;
				end
			println( "execute B instance" );
			[]char BInstance = "BInstance";
			[]char overrideInstance = "BOverrideInstance";
			[]char BInstanceFn()
				begin
					return "BInstanceFn";
				end
			[]char overrideInstanceFn()
				begin
					return "BOverrideInstanceFn";
				end
			println( "Create B instance " + count );
			count = count + 1;
	end

A a = new A;
A b = new B;
B c = new B;
println( "A.AStatic = " + A.AStatic );
println( "B.BStatic = " + B.BStatic );
println( "A.overrideStatic = " + A.overrideStatic );
println( "B.overrideStatic = " + B.overrideStatic );
println( "A.AStaticFn() = " + A.AStaticFn() );
println( "B.BStaticFn() = " + B.BStaticFn() );
println( "A.overrideStaticFn() = " + A.overrideStaticFn() );
println( "B.overrideStaticFn() = " + B.overrideStaticFn() );
println( "a.AInstance = " + a.AInstance );
println( "b.AInstance = " + b.AInstance );
println( "a.overrideInstance = " + a.overrideInstance );
println( "b.overrideInstance = " + b.overrideInstance );
println( "a.AInstanceFn() = " + a.AInstanceFn() );
println( "b.AInstanceFn() = " + b.AInstanceFn() );
println( "a.overrideInstanceFn() = " + a.overrideInstanceFn() );
println( "b.overrideInstanceFn() = " + b.overrideInstanceFn() );

println( "A.classType.isInstance( a ) = " + A.classType.isInstance( a ) );
println( "B.classType.isInstance( a ) = " + B.classType.isInstance( a ) );
println( "A.classType.isInstance( b ) = " + A.classType.isInstance( b ) );
println( "B.classType.isInstance( b ) = " + B.classType.isInstance( b ) );
