Commits

Dean Hall  committed 02ba6b2

#45: mainlining directly

  • Participants
  • Parent commits 931215c

Comments (0)

Files changed (12)

File src/tests/t002.c

     PM_RETURN_IF_ERROR(retval);
 
     retval = pm_run((uint8_t *)"t002");
+    pm_reportResult(retval);
     return (int)retval;
 }

File src/tests/t003.c

     PM_RETURN_IF_ERROR(retval);
 
     retval = pm_run((uint8_t *)"t003");
+    pm_reportResult(retval);
     return (int)retval;
 }

File src/tests/t006.c

     pimg -= 1;
     PM_ASSERT(*pimg == C_NULL);
 
+    pm_reportResult(retval);
     return retval;
 }
 

File src/tests/t009.c

     PM_RETURN_IF_ERROR(retval);
 
     retval = pm_run((uint8_t *)"t009");
+    pm_reportResult(retval);
     return (int)retval;
 }

File src/tests/t020.c

     PM_RETURN_IF_ERROR(retval);
 
     retval = pm_run((uint8_t *)"t020");
+    pm_reportResult(retval);
     return (int)retval;
 }

File src/tools/pmImgCreator.py

         # if creating usr lib, create placeholder in 0th index
         if self.imgtarget == "usr":
             self.nativetable.append((NATIVE_FUNC_PREFIX + "placeholder_func",
-                                    "\n/*\n"
-                                    " * Use placeholder because an index \n"
-                                    " * value of zero denotes the stdlib.\n"
-                                    " * This function should not be called.\n"
-                                    " */\n"
-                                    "return PM_RET_EX_SYS;\n"
+                                    "\n    /*\n"
+                                    "     * Use placeholder because an index \n"
+                                    "     * value of zero denotes the stdlib.\n"
+                                    "     * This function should not be called.\n"
+                                    "     */\n"
+                                    "    PmReturn_t retval;\n"
+                                    "    PM_RAISE(retval, PM_RET_EX_SYS, __LINE__);\n"
+                                    "    return retval;\n"
                                    ))
 
         # for each src file, convert and format

File src/vm/heap.c

 {
     PmReturn_t retval;
 
-    if (size < HEAP_MIN_CHUNK_SIZE) {
+    if (size < HEAP_MIN_CHUNK_SIZE) 
+    {
         size = HEAP_MIN_CHUNK_SIZE;
     }
 
-    /* Halt if size request is invalid */
-    if (size > HEAP_MAX_CHUNK_SIZE) {
-        PM_ERR(__LINE__);
+    /* If size request is invalid, raise a SystemError */
+    if (size > HEAP_MAX_CHUNK_SIZE) 
+    {
+        PM_RAISE(retval, PM_RET_EX_SYS, __LINE__);
+        return retval;
     }
 
 #ifdef TARGET_ARM

File src/vm/interp.c

  * Log
  * ---
  *
+ * 2006/09/29   #45: Finish interpret loop edits
  * 2006/09/10   #20: Implement assert statement
  * 2006/08/31   #9: Fix BINARY_SUBSCR for case stringobj[intobj]
  * 2006/08/30   #6: Have pmImgCreator append a null terminator to image list
  * Functions
  **************************************************************/
 
-/*
- * Halts via infinite loop.
- * Error report is in the registers containing
- * the parameters.  In avr-gcc these are regs R25-20.
- * TODO print values out SCI or on LCD
- */
-void
-py_err(uint16_t release, uint16_t file, uint16_t line)
-{
-    for(;;);
-}
-
-
 PmReturn_t
 interpret(pPmFunc_t pfunc)
 {
                 retval = int_negative(pobj1, &pobj2);
                 PM_BREAK_IF_ERROR(retval);
                 PM_PUSH(pobj2);
-                if (pobj2 == C_NULL)
-                {
-                    /* memory error? */
-                    PM_ERR(__LINE__);
-                }
                 continue;
 
             case UNARY_NOT:
                 retval = int_bitInvert(pobj1, &pobj2);
                 PM_BREAK_IF_ERROR(retval);
                 PM_PUSH(pobj2);
-                if (pobj2 == C_NULL)
-                {
-                    /* memory error? */
-                    PM_ERR(__LINE__);
-                }
                 continue;
 
             case BINARY_POWER:
                     /* ensure subscr is an int */
                     if (OBJ_GET_TYPE(*pobj1) != OBJ_TYPE_INT)
                     {
-                        PM_ERR(__LINE__);
+                        PM_RAISE(retval, PM_RET_EX_TYPE, __LINE__);
+                        break;
                     }
                     /* set the list item */
                     retval = list_setItem(pobj2,
                 break;
 
             case BINARY_LSHIFT:
-                /* if neither args are ints, TypeError */
-                if ((OBJ_GET_TYPE(*TOS) == OBJ_TYPE_INT)
-                    && (OBJ_GET_TYPE(*TOS1) == OBJ_TYPE_INT))
+                /* If either arg is not an int, raise a TypeError */
+                if ((OBJ_GET_TYPE(*TOS) != OBJ_TYPE_INT)
+                    || (OBJ_GET_TYPE(*TOS1) != OBJ_TYPE_INT))
                 {
-                    pobj1 = PM_POP();
-                    retval = int_new(
-                                ((pPmInt_t)PM_POP())->val <<
-                                ((pPmInt_t)pobj1)->val,
-                                &pobj2);
-                    PM_BREAK_IF_ERROR(retval);
-                    PM_PUSH(pobj2);
-                    continue;
+                    PM_RAISE(retval, PM_RET_EX_TYPE, __LINE__);
+                    break;
                 }
 
-                /* else it's a TypeError */
+                pobj1 = PM_POP();
+                retval = int_new(
+                            ((pPmInt_t)PM_POP())->val <<
+                            ((pPmInt_t)pobj1)->val,
+                            &pobj2);
+                PM_BREAK_IF_ERROR(retval);
+                PM_PUSH(pobj2);
+                continue;
+
+            case BINARY_RSHIFT:
+                /* If either arg is not an int, raise a TypeError */
+                if ((OBJ_GET_TYPE(*TOS) != OBJ_TYPE_INT)
+                    || (OBJ_GET_TYPE(*TOS1) != OBJ_TYPE_INT))
+                {
+                    PM_RAISE(retval, PM_RET_EX_TYPE, __LINE__);
+                    break;
+                }
+
+                pobj1 = PM_POP();
+                retval = int_new(
+                            ((pPmInt_t)PM_POP())->val >>
+                            ((pPmInt_t)pobj1)->val,
+                            &pobj2);
+                PM_BREAK_IF_ERROR(retval);
+                PM_PUSH(pobj2);
+                continue;
+
+            case BINARY_AND:
+                /* If either arg is not an int, raise a TypeError */
+                if ((OBJ_GET_TYPE(*TOS) != OBJ_TYPE_INT)
+                    || (OBJ_GET_TYPE(*TOS1) != OBJ_TYPE_INT))
+                {
+                    PM_RAISE(retval, PM_RET_EX_TYPE, __LINE__);
+                    break;
+                }
+
+                pobj1 = PM_POP();
+                retval = int_new(
+                            ((pPmInt_t)PM_POP())->val &
+                            ((pPmInt_t)pobj1)->val,
+                            &pobj2);
+                PM_BREAK_IF_ERROR(retval);
+                PM_PUSH(pobj2);
+                continue;
+
+            case BINARY_XOR:
+                /* If either arg is not an int, raise a TypeError */
+                if ((OBJ_GET_TYPE(*TOS) != OBJ_TYPE_INT)
+                    || (OBJ_GET_TYPE(*TOS1) != OBJ_TYPE_INT))
+                {
                 PM_RAISE(retval, PM_RET_EX_TYPE, __LINE__);
                 break;
-
-            case BINARY_RSHIFT:
-                /* if both objs are ints, perform the op */
-                if ((OBJ_GET_TYPE(*TOS) == OBJ_TYPE_INT)
-                    && (OBJ_GET_TYPE(*TOS1) == OBJ_TYPE_INT))
-                {
-                    pobj1 = PM_POP();
-                    retval = int_new(
-                                ((pPmInt_t)PM_POP())->val >>
-                                ((pPmInt_t)pobj1)->val,
-                                &pobj2);
-                    PM_BREAK_IF_ERROR(retval);
-                    PM_PUSH(pobj2);
-                    continue;
                 }
 
-                /* else it's a TypeError */
-                PM_RAISE(retval, PM_RET_EX_TYPE, __LINE__);
-                break;
-
-            case BINARY_AND:
-                /* if both objs are ints, perform the op */
-                if ((OBJ_GET_TYPE(*TOS) == OBJ_TYPE_INT)
-                    && (OBJ_GET_TYPE(*TOS1) == OBJ_TYPE_INT))
-                {
-                    pobj1 = PM_POP();
-                    retval = int_new(
-                                ((pPmInt_t)PM_POP())->val &
-                                ((pPmInt_t)pobj1)->val,
-                                &pobj2);
-                    PM_BREAK_IF_ERROR(retval);
-                    PM_PUSH(pobj2);
-                    continue;
-                }
-
-                /* else it's a TypeError */
-                PM_RAISE(retval, PM_RET_EX_TYPE, __LINE__);
-                break;
-
-            case BINARY_XOR:
-                /* if both objs are ints, perform the op */
-                if ((OBJ_GET_TYPE(*TOS) == OBJ_TYPE_INT)
-                    && (OBJ_GET_TYPE(*TOS1) == OBJ_TYPE_INT))
-                {
-                    pobj1 = PM_POP();
-                    retval = int_new(
-                                ((pPmInt_t)PM_POP())->val ^
-                                ((pPmInt_t)pobj1)->val,
-                                &pobj2);
-                    PM_BREAK_IF_ERROR(retval);
-                    PM_PUSH(pobj2);
-                    continue;
-                }
-
-                /* else it's a TypeError */
-                PM_RAISE(retval, PM_RET_EX_TYPE, __LINE__);
-                break;
+                pobj1 = PM_POP();
+                retval = int_new(
+                            ((pPmInt_t)PM_POP())->val ^
+                            ((pPmInt_t)pobj1)->val,
+                            &pobj2);
+                PM_BREAK_IF_ERROR(retval);
+                PM_PUSH(pobj2);
+                continue;
 
             case BINARY_OR:
-                /* if both objs are ints, perform the op */
-                if ((OBJ_GET_TYPE(*TOS) == OBJ_TYPE_INT)
-                    && (OBJ_GET_TYPE(*TOS1) == OBJ_TYPE_INT))
+                /* If either arg is not an int, raise a TypeError */
+                if ((OBJ_GET_TYPE(*TOS) != OBJ_TYPE_INT)
+                    || (OBJ_GET_TYPE(*TOS1) != OBJ_TYPE_INT))
                 {
-                    pobj1 = PM_POP();
-                    retval = int_new(
-                                ((pPmInt_t)PM_POP())->val |
-                                ((pPmInt_t)pobj1)->val,
-                                &pobj2);
-                    PM_BREAK_IF_ERROR(retval);
-                    PM_PUSH(pobj2);
-                    continue;
+                    PM_RAISE(retval, PM_RET_EX_TYPE, __LINE__);
+                    break;
                 }
-
-                /* else it's a TypeError */
-                PM_RAISE(retval, PM_RET_EX_TYPE, __LINE__);
-                break;
+                pobj1 = PM_POP();
+                retval = int_new(
+                            ((pPmInt_t)PM_POP())->val |
+                            ((pPmInt_t)pobj1)->val,
+                            &pobj2);
+                PM_BREAK_IF_ERROR(retval);
+                PM_PUSH(pobj2);
+                continue;
 
             case INPLACE_POWER:
             case PRINT_EXPR:
                 break;
 
             case INPLACE_LSHIFT:
-                /* if both objs are ints, perform the op */
-                if ((OBJ_GET_TYPE(*TOS) == OBJ_TYPE_INT)
-                    && (OBJ_GET_TYPE(*TOS1) == OBJ_TYPE_INT))
+                /* If either arg is not an int, raise a TypeError */
+                if ((OBJ_GET_TYPE(*TOS) != OBJ_TYPE_INT)
+                    || (OBJ_GET_TYPE(*TOS1) != OBJ_TYPE_INT))
                 {
-                    /* if target obj is a constant obj */
-                    if (OBJ_IS_CONST(*TOS1)) {
-                        pobj1 = PM_POP();
-                        retval = int_new(
-                                    ((pPmInt_t)PM_POP())->val <<
-                                    ((pPmInt_t)pobj1)->val,
-                                    &pobj2);
-                        PM_BREAK_IF_ERROR(retval);
-                        PM_PUSH(pobj2);
-                        continue;
-                    }
-
-                    /* otherwise do true in-place operation */
-                    else
-                    {
-                        ((pPmInt_t)TOS1)->val <<=
-                                ((pPmInt_t)TOS)->val;
-                        SP--;
-                        continue;
-                    }
+                    PM_RAISE(retval, PM_RET_EX_TYPE, __LINE__);
+                    break;
                 }
 
-                /* else it's a TypeError */
-                PM_RAISE(retval, PM_RET_EX_TYPE, __LINE__);
-                break;
+                /* If target obj is a constant obj */
+                if (OBJ_IS_CONST(*TOS1))
+                {
+                    pobj1 = PM_POP();
+                    retval = int_new(
+                                ((pPmInt_t)PM_POP())->val <<
+                                ((pPmInt_t)pobj1)->val,
+                                &pobj2);
+                    PM_BREAK_IF_ERROR(retval);
+                    PM_PUSH(pobj2);
+                    continue;
+                }
+
+                /* otherwise do true in-place operation */
+                else
+                {
+                    ((pPmInt_t)TOS1)->val <<=
+                            ((pPmInt_t)TOS)->val;
+                    SP--;
+                    continue;
+                }
 
             case INPLACE_RSHIFT:
-                /* if both objs are ints, perform the op */
-                if ((OBJ_GET_TYPE(*TOS) == OBJ_TYPE_INT)
-                    && (OBJ_GET_TYPE(*TOS1) == OBJ_TYPE_INT))
+                /* If either arg is not an int, raise a TypeError */
+                if ((OBJ_GET_TYPE(*TOS) != OBJ_TYPE_INT)
+                    || (OBJ_GET_TYPE(*TOS1) != OBJ_TYPE_INT))
                 {
-                    /* if target obj is a constant obj */
-                    if (OBJ_IS_CONST(*TOS1)) {
-                        pobj1 = PM_POP();
-                        retval = int_new(
-                                    ((pPmInt_t)PM_POP())->val >>
-                                    ((pPmInt_t)pobj1)->val,
-                                    &pobj2);
-                        PM_BREAK_IF_ERROR(retval);
-                        PM_PUSH(pobj2);
-                        continue;
-                    }
-
-                    /* otherwise do true in-place operation */
-                    else
-                    {
-                        ((pPmInt_t)TOS1)->val >>=
-                                ((pPmInt_t)TOS)->val;
-                        SP--;
-                        continue;
-                    }
+                    PM_RAISE(retval, PM_RET_EX_TYPE, __LINE__);
+                    break;
                 }
 
-                /* else it's a TypeError */
-                PM_RAISE(retval, PM_RET_EX_TYPE, __LINE__);
-                break;
+                /* if target obj is a constant obj */
+                if (OBJ_IS_CONST(*TOS1)) {
+                    pobj1 = PM_POP();
+                    retval = int_new(
+                                ((pPmInt_t)PM_POP())->val >>
+                                ((pPmInt_t)pobj1)->val,
+                                &pobj2);
+                    PM_BREAK_IF_ERROR(retval);
+                    PM_PUSH(pobj2);
+                    continue;
+                }
+
+                /* otherwise do true in-place operation */
+                else
+                {
+                    ((pPmInt_t)TOS1)->val >>=
+                            ((pPmInt_t)TOS)->val;
+                    SP--;
+                    continue;
+                }
 
             case INPLACE_AND:
-                /* if both objs are ints, perform the op */
-                if ((OBJ_GET_TYPE(*TOS) == OBJ_TYPE_INT)
-                    && (OBJ_GET_TYPE(*TOS1) == OBJ_TYPE_INT))
+                /* If either arg is not an int, raise a TypeError */
+                if ((OBJ_GET_TYPE(*TOS) != OBJ_TYPE_INT)
+                    || (OBJ_GET_TYPE(*TOS1) != OBJ_TYPE_INT))
                 {
-                    /* if target obj is a constant obj */
-                    if (OBJ_IS_CONST(*TOS1)) {
-                        pobj1 = PM_POP();
-                        retval = int_new(
-                                    ((pPmInt_t)PM_POP())->val &
-                                    ((pPmInt_t)pobj1)->val,
-                                    &pobj2);
-                        PM_BREAK_IF_ERROR(retval);
-                        PM_PUSH(pobj2);
-                        continue;
-                    }
-
-                    /* otherwise do true in-place operation */
-                    else
-                    {
-                        ((pPmInt_t)TOS1)->val &=
-                                ((pPmInt_t)TOS)->val;
-                        SP--;
-                        continue;
-                    }
+                    PM_RAISE(retval, PM_RET_EX_TYPE, __LINE__);
+                    break;
                 }
 
-                /* else it's a TypeError */
-                PM_RAISE(retval, PM_RET_EX_TYPE, __LINE__);
-                break;
+                /* if target obj is a constant obj */
+                if (OBJ_IS_CONST(*TOS1)) {
+                    pobj1 = PM_POP();
+                    retval = int_new(
+                                ((pPmInt_t)PM_POP())->val &
+                                ((pPmInt_t)pobj1)->val,
+                                &pobj2);
+                    PM_BREAK_IF_ERROR(retval);
+                    PM_PUSH(pobj2);
+                    continue;
+                }
+
+                /* otherwise do true in-place operation */
+                else
+                {
+                    ((pPmInt_t)TOS1)->val &=
+                            ((pPmInt_t)TOS)->val;
+                    SP--;
+                    continue;
+                }
 
             case INPLACE_XOR:
-                /* if both objs are ints, perform the op */
-                if ((OBJ_GET_TYPE(*TOS) == OBJ_TYPE_INT)
-                    && (OBJ_GET_TYPE(*TOS1) == OBJ_TYPE_INT))
+                /* If either arg is not an int, raise a TypeError */
+                if ((OBJ_GET_TYPE(*TOS) != OBJ_TYPE_INT)
+                    || (OBJ_GET_TYPE(*TOS1) != OBJ_TYPE_INT))
                 {
-                    /* if target obj is a constant obj */
-                    if (OBJ_IS_CONST(*TOS1)) {
-                        pobj1 = PM_POP();
-                        retval = int_new(
-                                    ((pPmInt_t)PM_POP())->val ^
-                                    ((pPmInt_t)pobj1)->val,
-                                    &pobj2);
-                        PM_BREAK_IF_ERROR(retval);
-                        PM_PUSH(pobj2);
-                        continue;
-                    }
-
-                    /* otherwise do true in-place operation */
-                    else
-                    {
-                        ((pPmInt_t)TOS1)->val ^=
-                                ((pPmInt_t)TOS)->val;
-                        SP--;
-                        continue;
-                    }
+                    PM_RAISE(retval, PM_RET_EX_TYPE, __LINE__);
+                    break;
                 }
 
-                /* else it's a TypeError */
-                PM_RAISE(retval, PM_RET_EX_TYPE, __LINE__);
-                break;
+                /* if target obj is a constant obj */
+                if (OBJ_IS_CONST(*TOS1)) {
+                    pobj1 = PM_POP();
+                    retval = int_new(
+                                ((pPmInt_t)PM_POP())->val ^
+                                ((pPmInt_t)pobj1)->val,
+                                &pobj2);
+                    PM_BREAK_IF_ERROR(retval);
+                    PM_PUSH(pobj2);
+                    continue;
+                }
+
+                /* otherwise do true in-place operation */
+                else
+                {
+                    ((pPmInt_t)TOS1)->val ^=
+                            ((pPmInt_t)TOS)->val;
+                    SP--;
+                    continue;
+                }
 
             case INPLACE_OR:
-                /* if both objs are ints, perform the op */
-                if ((OBJ_GET_TYPE(*TOS) == OBJ_TYPE_INT)
-                    && (OBJ_GET_TYPE(*TOS1) == OBJ_TYPE_INT))
+                /* If either arg is not an int, raise a TypeError */
+                if ((OBJ_GET_TYPE(*TOS) != OBJ_TYPE_INT)
+                    || (OBJ_GET_TYPE(*TOS1) != OBJ_TYPE_INT))
                 {
-                    /* if target obj is a constant obj */
-                    if (OBJ_IS_CONST(*TOS1)) {
-                        pobj1 = PM_POP();
-                        retval = int_new(
-                                    ((pPmInt_t)PM_POP())->val |
-                                    ((pPmInt_t)pobj1)->val,
-                                    &pobj2);
-                        PM_BREAK_IF_ERROR(retval);
-                        PM_PUSH(pobj2);
-                        continue;
-                    }
-
-                    /* otherwise do true in-place operation */
-                    else
-                    {
-                        ((pPmInt_t)TOS1)->val |=
-                                ((pPmInt_t)TOS)->val;
-                        SP--;
-                        continue;
-                    }
+                    PM_RAISE(retval, PM_RET_EX_TYPE, __LINE__);
+                    break;
                 }
 
-                /* else it's a TypeError */
-                PM_RAISE(retval, PM_RET_EX_TYPE, __LINE__);
-                break;
+                /* if target obj is a constant obj */
+                if (OBJ_IS_CONST(*TOS1)) {
+                    pobj1 = PM_POP();
+                    retval = int_new(
+                                ((pPmInt_t)PM_POP())->val |
+                                ((pPmInt_t)pobj1)->val,
+                                &pobj2);
+                    PM_BREAK_IF_ERROR(retval);
+                    PM_PUSH(pobj2);
+                    continue;
+                }
+
+                /* otherwise do true in-place operation */
+                else
+                {
+                    ((pPmInt_t)TOS1)->val |=
+                            ((pPmInt_t)TOS)->val;
+                    SP--;
+                    continue;
+                }
 
             case BREAK_LOOP:
                 {
                     /* ensure there's a block */
                     if (pb1 == C_NULL)
                     {
-                        PM_ERR(__LINE__);
+                        PM_RAISE(retval, PM_RET_EX_SYS, __LINE__);
+                        break;
                     }
 
                     /* delete blocks until first loop block */
                 {
                     /* get ptr to top block */
                     pPmBlock_t pb = FP->fo_blockstack;
-                    /* if there's a block */
-                    if (pb != C_NULL)
+                    /* If there's no block, raise SystemError */
+                    if (pb == C_NULL)
                     {
-                        /* pop block */
-                        FP->fo_blockstack = pb->next;
-                        /* set stack to previous level */
-                        SP = pb->b_sp;
-                        /* delete block */
-                        heap_freeChunk((pPmObj_t)pb);
-                        continue;
+                        PM_RAISE(retval, PM_RET_EX_SYS, __LINE__);
+                        break;
                     }
 
-                    /* SystemError, nonexistent block */
-                    PM_RAISE(retval, PM_RET_EX_SYS, __LINE__);
-                    break;
+                    /* pop block */
+                    FP->fo_blockstack = pb->next;
+                    /* set stack to previous level */
+                    SP = pb->b_sp;
+                    /* delete block */
+                    heap_freeChunk((pPmObj_t)pb);
+                    continue;
+
                 }
 
             case END_FINALLY:
                 /* get num args */
                 t16 = GET_ARG();
                 /* ensure no keyword args */
-                if ((t16 > 255) || (t16 < 0))
+                if ((t16 & (uint16_t)0xFF00) != 0)
                 {
-                    PM_ERR(__LINE__);
+                    PM_RAISE(retval, PM_RET_EX_SYS, __LINE__);
+                    break;
                 }
                 /* get the func */
                 pobj1 = STACK(t16);
                     /* ensure num args fits in native frame */
                     if (t16 > NATIVE_NUM_LOCALS)
                     {
-                        PM_ERR(__LINE__);
+                        PM_RAISE(retval, PM_RET_EX_SYS, __LINE__);
+                        break;
                     }
 
                     /* keep numargs */

File src/vm/interp.h

  **************************************************************/
 
 /**
- * System error, immediate halt with report.
- *
- * @param   release ID of the interpreter release.
- * @param   file ID of the interpreter file reporting the error.
- * @param   line Line number of the interpreter file 
- *               reporting the error.
- */
-void py_err(uint16_t release, uint16_t file, uint16_t line);
-
-
-/**
  * Interpret the function's bcode.
  *
  * The given obj may be a function, module, or class.

File src/vm/obj.c

             retval = tuple_loadFromImg(memspace, paddr, r_pobj);
             break;
 
-        case OBJ_TYPE_LST:
-        case OBJ_TYPE_DIC:
-        case OBJ_TYPE_COB:
-        case OBJ_TYPE_MOD:
-        case OBJ_TYPE_CLO:
-        case OBJ_TYPE_FXN:
-        case OBJ_TYPE_CLI:
-            /* these types should not be in an img obj */
-            PM_RAISE(retval, PM_RET_EX_SYS, __LINE__);
-            return retval;
-
         /* if it's a native code img, load into a code obj */
         case OBJ_TYPE_NIM:
             retval = no_loadFromImg(memspace, paddr, r_pobj);
             retval = co_loadFromImg(memspace, paddr, r_pobj);
             break;
 
+        /* All other types should not be in an img obj */
         default:
-            /* XXX invalid type for image obj */
-            PM_ERR(__LINE__);
+            PM_RAISE(retval, PM_RET_EX_SYS, __LINE__);
+            break;
     }
     return retval;
 }
 
     return retval;
 }
+
+
+#ifdef TARGET_DESKTOP
+#include "stdio.h"
+
+void pm_reportResult(PmReturn_t result)
+{
+    if (result == PM_RET_OK)
+    {
+        puts("Ok.");
+    }
+    else if (result >= PM_RET_ASSERT_FAIL)
+    {
+        puts("Error.");
+    }
+    else
+    {
+        printf("Exception: 0x%0X\n", result);
+        printf("  Release: 0x%0X\n", gVmGlobal.errVmRelease);
+        printf("  FileId:  0x%0X\n", gVmGlobal.errFileId);
+        printf("  LineNum: %d\n", gVmGlobal.errLineNum);
+    }
+}
+#endif /* TARGET_DESKTOP */
  * Macros
  **************************************************************/
 
-/** 
- * Returns an exception error code and stores debug data 
+/**
+ * Returns an exception error code and stores debug data
  *
  * This macro must be used as an rval statement.  That is, it must
  * be used after an assignment such as "retval = " or a return statement
  */
-#if __DEBUG__
+#define __DEBUG__
+#ifdef __DEBUG__
 #define PM_RAISE(retexn, exn, line) \
         do \
         { \
         retexn = (exn)
 #endif
 
-/** puts debug info in registers, halts interpreter */
-#if __DEBUG__
-#define PM_ERR(line)                        \
-        gVmGlobal.errFileId = __FILE_ID__;  \
-        gVmGlobal.errLineNum = (uint16_t)(line); \
-        retval = PM_RET_ERR;                \
-        for(;;)
-#else
-#define PM_ERR(line)                        \
-        gVmGlobal.errFileId = __FILE_ID__;  \
-        gVmGlobal.errLineNum = (uint16_t)(line); \
-        retval = PM_RET_ERR;                \
-        return PM_RET_ERR
-#endif
-
 /** error macro for unit tests */
 #define TEST_ERR(arg)   for(;;)
 
  **************************************************************/
 
 /**
- * Initializes the PyMite virtual machine and  indexes the user's application 
+ * Initializes the PyMite virtual machine and indexes the user's application
  * image.  The VM heap and globals are reset.  The argument, pusrimg, may be
  * null for interactive sessions.
  *
 PmReturn_t pm_run(uint8_t *modstr);
 
 
+#ifdef TARGET_DESKTOP
+/**
+ * Reports the return status to stdout and prints exception info if raised
+ *
+ * @param result        Return status from pm_run()
+ */
+void pm_reportResult(PmReturn_t result);
+#endif /* TARGET_DESKTOP */
+
 #endif /* __PM_H__ */