function Typename(obj)
{
	var t = type(obj);
	if(t == TYPE_INTEGER)
	{
		return "Integer";
	}
	if(t == TYPE_REAL)
	{
		return "Real";
	}
	if(t == TYPE_STRING)
	{
		return "String";
	}
	if(t == TYPE_DICTIONARY)
	{
		return obj.typename;
	}
	return "Unknown";
}

function Vec3(x, y, z)
{
	var obj = {};
	obj.typename = "Vec3";
	obj.x = x;
	obj.y = y;
	obj.z = z;
	obj.Add = function(o)
	{
		if(Typename(o) != "Vec3")
		{
			throw "cannot add with non-Vec3";
		}
		return Vec3(this.x + o.x, this.y + o.y, this.z + o.z);
	};
	obj.Sub = function(o)
	{
		if(Typename(o) != "Vec3")
		{
			throw "cannot add with non-Vec3";
		}
		return Vec3(this.x - o.x, this.y - o.y, this.z - o.z);
	};
	obj.Mul = function(o)
	{
		return Vec3(this.x * o, this.y * o, this.z * o);
	};
	obj.Dot = function(o)
	{
		if(Typename(o) != "Vec3")
		{
			throw "cannot add with non-Vec3";
		}
		return this.x * o.x + this.y + o.y + this.z * o.z;
	};
	obj.Len = function()
	{
		return (this.x^2  + this.y^2 + this.z^2)^0.5;
	};
	return obj;
}