Changeset 188de86 in git for Singular/pyobject.cc


Ignore:
Timestamp:
Aug 2, 2012, 4:09:13 PM (11 years ago)
Author:
Hans Schoenemann <hannes@…>
Branches:
(u'jengelh-datetime', 'ceac47cbc86fe4a15902392bdbb9bd2ae0ea02c6')(u'spielwiese', 'c987db42cd2ec943b97ac5746c99892ceddf909c')
Children:
4f9652847609cefd5ff3b91d14f34611592ab699
Parents:
0419aba8292e7109329604d8ad03b70f8ef6542344a1c2199e33375a631289eaab7a81954c8383e2
Message:
Merge pull request #158 from alexanderdreyer/spielwiese

Transfering newstruct and pyobject fixes to Spielwiese
File:
1 edited

Legend:

Unmodified
Added
Removed
  • Singular/pyobject.cc

    r0419ab r188de86  
    1616#include <kernel/mod2.h>
    1717#include <misc/auxiliary.h>
     18#include "newstruct.h"
    1819
    1920#include <omalloc/omalloc.h>
    2021
    2122#include <kernel/febase.h>
    22 // #include <kernel/longrat.h>
     23#include <kernel/intvec.h>
    2324
    2425#include "subexpr.h"
     
    110111
    111112  PythonObject(): m_ptr(Py_None) { }
    112   PythonObject(ptr_type ptr): m_ptr(ptr) {if (!ptr) handle_exception();}
     113  PythonObject(ptr_type ptr): m_ptr(ptr) {
     114    if (!ptr && handle_exception()) m_ptr = Py_None;
     115  }
    113116
    114117  ptr_type check_context(ptr_type ptr) const {
     
    129132      return *this;
    130133
    131     Werror("unary op %d not implemented for pyobject", op);
    132     return self();
     134    return self(NULL);
    133135  }
    134136
     
    149151      case '.': case COLONCOLON: case ATTRIB_CMD: return attr(arg);
    150152    }
    151     Werror("binary op %d not implemented for pyobject!", op);
    152 
    153     return self();
     153    return self(NULL);
    154154  }
    155155
     
    159159    switch(op)
    160160    {
    161       case ATTRIB_CMD: PyObject_SetAttr(*this, arg1, arg2); return self();
    162     }
    163 
    164     Werror("ternary op %d not implemented for pyobject!", op);
    165     return self();
     161      case ATTRIB_CMD:
     162        if(PyObject_SetAttr(*this, arg1, arg2) == -1) handle_exception();
     163        return self();
     164    }
     165    return self(NULL);
    166166  }
    167167
     
    186186  BOOLEAN assign_to(leftv result)
    187187  {
    188     return (m_ptr == Py_None? none_to(result): python_to(result));
     188    return (m_ptr? (m_ptr == Py_None? none_to(result): python_to(result)): TRUE);
    189189  }
    190190
     
    229229  }
    230230
    231   void handle_exception() {
     231  BOOLEAN handle_exception() const {
     232
     233    if(!PyErr_Occurred()) return FALSE;
    232234   
    233235    PyObject *pType, *pMessage, *pTraceback;
     
    242244   
    243245    PyErr_Clear();
     246    return TRUE;
    244247  }
    245248
     
    268271  BOOLEAN none_to(leftv result) const
    269272  {
     273    Py_XDECREF(m_ptr);
    270274    result->data = NULL;
    271275    result->rtyp = NONE;
     
    276280  {
    277281    result->data = m_ptr;
     282    Py_XINCREF(m_ptr);
    278283    result->rtyp = PythonInterpreter::id();
    279284    return !m_ptr;
     
    295300class PythonCastStatic:
    296301  public PythonObject {
     302  typedef PythonCastStatic self;
    297303public:
    298304
     
    306312  ptr_type get(ptr_type value)       { return value; }
    307313  ptr_type get(long value)           { return PyInt_FromLong(value); }
     314  ptr_type get(int value)            { return PyInt_FromLong((long)value); }
    308315  ptr_type get(const char* value)    { return PyString_FromString(value); }
    309316  ptr_type get(char* value) { return get(const_cast<const char*>(value)); }
     317  ptr_type get(intvec* value);       // inlined below
    310318  ptr_type get(lists value);         // inlined after PythonObjectDynamic
    311319};
    312320
    313 
     321template <class CastType>
     322inline PythonObject::ptr_type
     323PythonCastStatic<CastType>::get(intvec* value)
     324{
     325  ptr_type pylist(PyList_New(0));
     326  for (int idx = 0; idx < value->length(); ++idx)
     327    PyList_Append(pylist, self::get((*value)[idx]));
     328
     329  return pylist;
     330}
    314331
    315332/** @class PythonCastDynamic
     
    334351    case STRING_CMD: return PythonCastStatic<const char*>(value);
    335352    case LIST_CMD:   return PythonCastStatic<lists>(value);
    336       //    case UNKNOWN:    return PythonCastStatic<const char*>((void*)value->Name());
    337     }
    338    
    339     Werror("type # %d incompatible with pyobject", typeId);
     353    case INTVEC_CMD: return PythonCastStatic<intvec*>(value);
     354    }
     355
     356    sleftv tmp;
     357    BOOLEAN newstruct_equal(int, leftv, leftv); // declaring overloaded '='
     358    if (!newstruct_equal(PythonInterpreter::id(), &tmp, value)) 
     359      return PythonCastStatic<>(&tmp);       
     360
     361    if (typeId > MAX_TOK)       // custom types
     362    {
     363      blackbox *bbx = getBlackboxStuff(typeId);
     364      assume(bbx != NULL);
     365      if (! bbx->blackbox_Op1(PythonInterpreter::id(), &tmp, value))
     366        return PythonCastStatic<>(&tmp);       
     367    }
     368
     369    Werror("type '%s` incompatible with 'pyobject`", iiTwoOps(typeId));
    340370    return PythonObject();
    341371  }
     
    347377{
    348378  ptr_type pylist(PyList_New(0));
    349   for (size_t i = 0; i <= value->nr; ++i)
     379  for (int i = 0; i <= value->nr; ++i)
    350380    PyList_Append(pylist, PythonCastDynamic((value->m) + i));
    351381
     
    416446  PyRun_SimpleString(reinterpret_cast<const char*>(arg->Data()));
    417447  sync_contexts();
     448
     449  Py_XINCREF(Py_None);
    418450  return PythonCastStatic<>(Py_None).assign_to(result);
    419451}
     
    448480  sync_contexts();
    449481
     482  Py_XINCREF(Py_None);
    450483  return PythonCastStatic<>(Py_None).assign_to(result);
    451484}
     
    454487void* pyobject_Init(blackbox*)
    455488{
     489  Py_XINCREF(Py_None);
    456490  return Py_None;
    457491}
     
    495529      long value = PyInt_AsLong(PythonCastStatic<>(head));
    496530      if( (value == -1) &&  PyErr_Occurred() ) {
    497         Werror("pyobject cannot be converted to integer");
     531        Werror("'pyobject` cannot be converted to integer");
    498532        PyErr_Clear();
    499533        return TRUE;
     
    506540      res->data = (void*) omStrDup("pyobject");
    507541      res->rtyp = STRING_CMD; 
    508       return FALSE;
    509 
    510   case LIST_CMD:
     542      return FALSE;
     543  }
     544
     545  if (!PythonCastStatic<>(head)(op).assign_to(res))
    511546    return FALSE;
    512547
    513   }
    514   return PythonCastStatic<>(head)(op).assign_to(res);
     548  BOOLEAN newstruct_Op1(int, leftv, leftv); // forward declaration
     549  return newstruct_Op1(op, res, head);
    515550}
    516551
     
    532567      return lhs.attr(get_attrib_name(arg2)).assign_to(res);
    533568  }
     569
    534570  PythonCastDynamic rhs(arg2);
    535   return lhs(op, rhs).assign_to(res);
     571  if (!lhs(op, rhs).assign_to(res))
     572    return FALSE;
     573
     574  BOOLEAN newstruct_Op2(int, leftv, leftv, leftv); // forward declaration
     575  return newstruct_Op2(op, res, arg1, arg2);
     576
    536577}
    537578
     
    543584  PythonCastDynamic rhs2(arg3);
    544585
    545   return lhs(op, rhs1, rhs2).assign_to(res);
     586  if (!lhs(op, rhs1, rhs2).assign_to(res))
     587    return FALSE;
     588
     589  return blackboxDefaultOp3(op, res, arg1, arg2, arg3);
    546590}
    547591
     
    550594BOOLEAN pyobject_OpM(int op, leftv res, leftv args)
    551595{
    552   typedef PythonCastStatic<PythonObject::sequence_tag> seq_type;
    553 
    554596  switch(op)                    // built-in return types first
    555597  {
     
    561603      return FALSE;
    562604    }
    563   }
    564 
     605
     606    case INTVEC_CMD:
     607      PythonObject obj = PythonCastStatic<>(args->Data());
     608      unsigned long len = obj.size();
     609
     610      intvec* vec = new intvec(len);
     611      for(unsigned long idx = 0; idx != len; ++idx) {
     612        long value = PyInt_AsLong(obj[idx]);
     613        (*vec)[idx] = static_cast<int>(value);
     614
     615        if ((value == -1) &&  PyErr_Occurred()) {
     616          value = 0;
     617          PyErr_Clear();
     618        }
     619        if (value != long((*vec)[idx])) {
     620          delete vec;
     621          Werror("'pyobject` cannot be converted to intvec");
     622          return TRUE;
     623        }
     624      }
     625      res->data = (void *)vec;
     626      res->rtyp = op;
     627      return FALSE;
     628  }
    565629  typedef PythonCastStatic<PythonObject::sequence_tag> seq_type;
    566   return PythonCastStatic<>(args)(op, seq_type(args->next)).assign_to(res);
     630  if (! PythonCastStatic<>(args)(op, seq_type(args->next)).assign_to(res))
     631    return FALSE;
     632
     633  BOOLEAN newstruct_OpM(int, leftv, leftv); // forward declaration
     634  return newstruct_OpM(op, res, args);
    567635}
    568636
     
    637705  b->blackbox_Op3     = pyobject_Op3;
    638706  b->blackbox_OpM     = pyobject_OpM;
     707  b->data             = omAlloc0(newstruct_desc_size());
    639708
    640709  PythonInterpreter::init(setBlackboxStuff(b,"pyobject"));
Note: See TracChangeset for help on using the changeset viewer.