Add staticmethod and classmethod to builtin namespace.
diff --git a/py/obj.h b/py/obj.h
index 2f4d441..660ac66 100644
--- a/py/obj.h
+++ b/py/obj.h
@@ -66,11 +66,11 @@
 // These macros are used to declare and define constant staticmethond and classmethod objects
 // You can put "static" in front of the definitions to make them local
 
-#define MP_DECLARE_CONST_STATICMETHOD_OBJ(obj_name) extern const mp_obj_staticmethod_t obj_name
-#define MP_DECLARE_CONST_CLASSMETHOD_OBJ(obj_name) extern const mp_obj_classmethod_t obj_name
+#define MP_DECLARE_CONST_STATICMETHOD_OBJ(obj_name) extern const mp_obj_static_class_method_t obj_name
+#define MP_DECLARE_CONST_CLASSMETHOD_OBJ(obj_name) extern const mp_obj_static_class_method_t obj_name
 
-#define MP_DEFINE_CONST_STATICMETHOD_OBJ(obj_name, fun_name) const mp_obj_staticmethod_t obj_name = {{&mp_type_staticmethod}, fun_name}
-#define MP_DEFINE_CONST_CLASSMETHOD_OBJ(obj_name, fun_name) const mp_obj_classmethod_t obj_name = {{&mp_type_classmethod}, fun_name}
+#define MP_DEFINE_CONST_STATICMETHOD_OBJ(obj_name, fun_name) const mp_obj_static_class_method_t obj_name = {{&mp_type_staticmethod}, fun_name}
+#define MP_DEFINE_CONST_CLASSMETHOD_OBJ(obj_name, fun_name) const mp_obj_static_class_method_t obj_name = {{&mp_type_classmethod}, fun_name}
 
 // Need to declare this here so we are not dependent on map.h
 struct _mp_map_t;
@@ -180,7 +180,6 @@
     abs             float complex
     hash            bool int none str
     equal           int str
-    less            int
     get_array_n     tuple list
 
     unpack seq      list tuple
@@ -389,15 +388,11 @@
 extern const mp_obj_type_t mp_type_staticmethod;
 extern const mp_obj_type_t mp_type_classmethod;
 
-typedef struct _mp_obj_staticmethod_t {
+// this structure is used for instances of both staticmethod and classmethod
+typedef struct _mp_obj_static_class_method_t {
     mp_obj_base_t base;
     mp_obj_t fun;
-} mp_obj_staticmethod_t;
-
-typedef struct _mp_obj_classmethod_t {
-    mp_obj_base_t base;
-    mp_obj_t fun;
-} mp_obj_classmethod_t;
+} mp_obj_static_class_method_t;
 
 // sequence helpers
 void mp_seq_multiply(const void *items, uint item_sz, uint len, uint times, void *dest);
diff --git a/py/objtype.c b/py/objtype.c
index 6934cb3..6ff18b4 100644
--- a/py/objtype.c
+++ b/py/objtype.c
@@ -212,10 +212,10 @@
             // TODO check that this is the correct place to have this logic
             if (MP_OBJ_IS_TYPE(member, &mp_type_staticmethod)) {
                 // return just the function
-                dest[0] = ((mp_obj_staticmethod_t*)member)->fun;
+                dest[0] = ((mp_obj_static_class_method_t*)member)->fun;
             } else if (MP_OBJ_IS_TYPE(member, &mp_type_classmethod)) {
                 // return a bound method, with self being the type of this object
-                dest[0] = ((mp_obj_classmethod_t*)member)->fun;
+                dest[0] = ((mp_obj_static_class_method_t*)member)->fun;
                 dest[1] = mp_obj_get_type(self_in);
             } else {
                 // return a bound method, with self being this object
@@ -304,10 +304,10 @@
         // see http://docs.python.org/3.3/howto/descriptor.html
         if (MP_OBJ_IS_TYPE(member, &mp_type_staticmethod)) {
             // return just the function
-            dest[0] = ((mp_obj_staticmethod_t*)member)->fun;
+            dest[0] = ((mp_obj_static_class_method_t*)member)->fun;
         } else if (MP_OBJ_IS_TYPE(member, &mp_type_classmethod)) {
             // return a bound method, with self being this class
-            dest[0] = ((mp_obj_classmethod_t*)member)->fun;
+            dest[0] = ((mp_obj_static_class_method_t*)member)->fun;
             dest[1] = self_in;
         } else {
             // return just the function
@@ -417,10 +417,10 @@
                 // TODO check that this is the correct place to have this logic
                 if (MP_OBJ_IS_TYPE(member, &mp_type_staticmethod)) {
                     // return just the function
-                    dest[0] = ((mp_obj_staticmethod_t*)member)->fun;
+                    dest[0] = ((mp_obj_static_class_method_t*)member)->fun;
                 } else if (MP_OBJ_IS_TYPE(member, &mp_type_classmethod)) {
                     // return a bound method, with self being the type of this object
-                    dest[0] = ((mp_obj_classmethod_t*)member)->fun;
+                    dest[0] = ((mp_obj_static_class_method_t*)member)->fun;
                     dest[1] = mp_obj_get_type(self->obj);
                 } else {
                     // return a bound method, with self being this object
@@ -507,12 +507,26 @@
 /******************************************************************************/
 // staticmethod and classmethod types (probably should go in a different file)
 
+static mp_obj_t static_class_method_make_new(mp_obj_t self_in, uint n_args, uint n_kw, const mp_obj_t *args) {
+    assert(self_in == &mp_type_staticmethod || self_in == &mp_type_classmethod);
+
+    if (n_args != 1 || n_kw != 0) {
+        nlr_jump(mp_obj_new_exception_msg_1_arg(MP_QSTR_TypeError, "function takes 1 positional argument but %d were given", (void*)(machine_int_t)n_args));
+    }
+
+    mp_obj_static_class_method_t *o = m_new_obj(mp_obj_static_class_method_t);
+    *o = (mp_obj_static_class_method_t){{(mp_obj_type_t*)self_in}, args[0]};
+    return o;
+}
+
 const mp_obj_type_t mp_type_staticmethod = {
     { &mp_const_type },
     "staticmethod",
+    .make_new = static_class_method_make_new
 };
 
 const mp_obj_type_t mp_type_classmethod = {
     { &mp_const_type },
     "classmethod",
+    .make_new = static_class_method_make_new
 };
diff --git a/py/qstrdefs.h b/py/qstrdefs.h
index dcd4ba4..b90c502 100644
--- a/py/qstrdefs.h
+++ b/py/qstrdefs.h
@@ -51,6 +51,7 @@
 Q(bytes)
 Q(callable)
 Q(chr)
+Q(classmethod)
 Q(complex)
 Q(dict)
 Q(dir)
@@ -80,6 +81,7 @@
 Q(repr)
 Q(set)
 Q(sorted)
+Q(staticmethod)
 Q(sum)
 Q(super)
 Q(str)
diff --git a/py/runtime.c b/py/runtime.c
index fc18c01..6790da4 100644
--- a/py/runtime.c
+++ b/py/runtime.c
@@ -134,6 +134,9 @@
     mp_map_add_qstr(&map_builtins, MP_QSTR_type, (mp_obj_t)&mp_const_type);
     mp_map_add_qstr(&map_builtins, MP_QSTR_zip, (mp_obj_t)&zip_type);
 
+    mp_map_add_qstr(&map_builtins, MP_QSTR_classmethod, (mp_obj_t)&mp_type_classmethod);
+    mp_map_add_qstr(&map_builtins, MP_QSTR_staticmethod, (mp_obj_t)&mp_type_staticmethod);
+
     mp_obj_t m_array = mp_obj_new_module(MP_QSTR_array);
     rt_store_attr(m_array, MP_QSTR_array, (mp_obj_t)&array_type);
 
@@ -876,10 +879,10 @@
                         // see http://docs.python.org/3.3/howto/descriptor.html
                         if (MP_OBJ_IS_TYPE(meth->fun, &mp_type_staticmethod)) {
                             // return just the function
-                            dest[0] = ((mp_obj_staticmethod_t*)meth->fun)->fun;
+                            dest[0] = ((mp_obj_static_class_method_t*)meth->fun)->fun;
                         } else if (MP_OBJ_IS_TYPE(meth->fun, &mp_type_classmethod)) {
                             // return a bound method, with self being the type of this object
-                            dest[0] = ((mp_obj_classmethod_t*)meth->fun)->fun;
+                            dest[0] = ((mp_obj_static_class_method_t*)meth->fun)->fun;
                             dest[1] = mp_obj_get_type(base);
                         } else {
                             // return a bound method, with self being this object
@@ -970,6 +973,8 @@
 }
 
 mp_obj_t rt_import_name(qstr name, mp_obj_t fromlist, mp_obj_t level) {
+    DEBUG_printf("import name %s\n", qstr_str(name));
+
     // build args array
     mp_obj_t args[5];
     args[0] = MP_OBJ_NEW_QSTR(name);
@@ -983,6 +988,8 @@
 }
 
 mp_obj_t rt_import_from(mp_obj_t module, qstr name) {
+    DEBUG_printf("import from %p %s\n", module, qstr_str(name));
+
     mp_obj_t x = rt_load_attr(module, name);
     /* TODO convert AttributeError to ImportError
     if (fail) {