Logo Search packages:      
Sourcecode: kaya version File versions  Download package

ValueFuns.cc

/**
    Kaya run-time system
    Copyright (C) 2004, 2005 Edwin Brady

    This file is distributed under the terms of the GNU Lesser General
    Public Licence. See COPYING for licence.
*/

#include "VMState.h"
#include "VM.h"
#include "Heap.h"
#include "ValueFuns.h"
#include "stdfuns.h"
#include "Closure.h"

/*
FunTable* inttable = new IntTable();
FunTable* stringtable = new StringTable();
FunTable* fntable = new FnTable();
FunTable* arraytable = new ArrayTable();
FunTable* uniontable = new UnionTable();
FunTable* exceptiontable = new ExceptionTable();
FunTable* realtable = new RealTable();
*/

/// Functions on int

kint inttable_eq(Value* x, Value* y)
{
    return (x->getInt()==y->getInt());
}

kint inttable_cmp(Value* x, Value* y)
{
    int xi = x->getInt();
    int yi = y->getInt();
    if (xi<yi) return -1;
    else if (xi==yi) return 0;
    else return 1;
}

Value* inttable_copy(Value* x, map<Value*,Value*>& done)
{
    return new Value((void*)(x->getInt()),KVT_INT);
}
Value* inttable_fastcopy(Value* x)
{
    return new Value((void*)(x->getInt()),KVT_INT);
}

Value* inttable_marshal(VMState* vm,vector<Value*>& done,Value* x, int id)
{
    Value* v = new Value(NULL,KVT_STRING);
    wchar_t buf[50];
    SWPRINTF(buf,50,L"[%d]I[%d]",id,x->getInt());
    v->setString(new String(buf));
    return v;
}

Value* inttable_hash(Value* x)
{
    return new Value((void*)(x->getInt()),KVT_INT);
}

int inttable_memusage(Value* x)
{
    return sizeof(x);
}

/// Functions on String

kint stringtable_eq(Value* x, Value* y)
{
    return (x->getString()->eq(y->getString()));
}

kint stringtable_cmp(Value* x, Value* y)
{
    int ret = x->getString()->cmp(y->getString());
    if (ret<0)
      return -1;
    else if (ret>0)
      return 1;
    else return 0;
}

Value* stringtable_copy(Value* x, map<Value*,Value*>& done)
{
    return MKSTR(x->getString()->getVal());
}
Value* stringtable_fastcopy(Value* x)
{
    return MKSTR(x->getString()->getVal());
}

Value* stringtable_marshal(VMState* vm,vector<Value*>& done,Value* x, int id)
{
    Value* v = new Value(NULL,KVT_STRING);
    String* s = x->getString();
    int len = s->length();
    int sz = len+43;
    wchar_t buf[sz];
    //    cout <<  << endl;
#ifdef WIN32
    SWPRINTF(buf,sz,L"[%d]S[[%d][%d]%s]",id,len,s->space(),s->getVal());
#else
    SWPRINTF(buf,sz,L"[%d]S[[%d][%d]%S]",id,len,s->space(),s->getVal());
#endif
    v->setString(new String(buf));
    return v;
}

Value* stringtable_hash(Value* x)
{
    return new Value((void*)x->getString()->hash(),KVT_INT);
}

int stringtable_memusage(Value* x)
{
    return sizeof(String)+(x->getString()->space()*sizeof(wchar_t));
}

/// Functions on closures

kint fntable_eq(Value* x, Value* y)
{
    return (x->getFunc()->eq(y->getFunc()));
}

/// This is probably quite meaningless
kint fntable_cmp(Value* x, Value* y)
{
    return (kint)(x->getRaw())-(kint)(y->getRaw());
//    kaya_throw("Can't compare closures sensibly",1);
//    return new Value(0,inttable);
}

Value* fntable_copy(Value* x, map<Value*,Value*>& done)
{
    return new Value((void*)(x->getFunc()->copy(done)),KVT_FUNC);
}

Value* fntable_marshal(VMState* vm,vector<Value*>& done,Value* x, int id)
{
    // Check for circles.
    int idx;
    vector<Value*>::iterator it = done.begin();
    for(idx=0;it!=done.end();++it,++idx) {
      if ((*it)==x) {
          // Already done it, just spit out a reference to it.
          wchar_t buf[20];
          SWPRINTF(buf,20,L"[%d]C[%d]",id,idx);
          return new Value(new String(buf),KVT_STRING);
      }
    }
    idx = done.size();
    done.push_back(x);

    Closure *c = x->getFunc();
    wchar_t buf[21];
    SWPRINTF(buf,21,L"[%d]F[[%d]",id,idx);
    String* mclos = new String(buf);
    wchar_t cfnid[50];
    SWPRINTF(cfnid,50,L"[%d][%d]",c->getFnID(),c->getNumArgs());
    mclos->append(cfnid);
    Value** cargs = c->getArgs();

    for(int i=0;i<c->getNumArgs();i++) {
      wchar_t* el = funtable_marshal_aux(vm,done,cargs[i],id);
      mclos->append(el);
    }
    mclos->append(L"]");
    return new Value(mclos,KVT_STRING);
//    vm->kaya_throw("Can't marshal closures sensibly",1);
//    return new Value(new String("<<closure>>"),stringtable);
}

Value* fntable_hash(Value* x)
{
    // FIXME: Do this. Not sure functions will hash sensibly.
    return 0;
}

int fntable_memusage(Value* x)
{
    int size = sizeof(Value)+sizeof(Closure);
    Value** args = x->getFunc()->getArgs();
    for(int i=0;i<x->getFunc()->getNumArgs();++i) {
      size+=4;
      size+=funtable_memusage(args[i]);
    }
    return size;
}

/// Functions on Reals

kint realtable_eq(Value* x, Value* y)
{
    return (x->getReal()==y->getReal());
}

kint realtable_cmp(Value* x, Value* y)
{
    double xv = x->getReal();
    double yv = y->getReal();
    if (yv>xv) return -1;
    else if (yv==xv) return 0;
    else return 1;
}

Value* realtable_copy(Value* x, map<Value*,Value*>& done)
{
    double xv = x->getReal();
    Value* v=new Value(NULL,KVT_REAL);
    v->setReal(xv);
    return v;
}
Value* realtable_fastcopy(Value* x)
{
    double xv = x->getReal();
    Value* v=new Value(NULL,KVT_REAL);
    v->setReal(xv);
    return v;
}

Value* realtable_marshal(VMState* vm,vector<Value*>& done,Value* x, int id)
{
    Value* v = new Value(NULL,KVT_STRING);
    wchar_t buf[255];
    SWPRINTF(buf,255,L"[%d]R[%e]",id,x->getReal());
    v->setString(new String(buf));
    return v;
}

Value* realtable_hash(Value* x)
{
    vector<Value*> done;
    Value* s = realtable_marshal(NULL,done,x,0);
    return new Value((void*)s->getString()->hash(),KVT_INT);
}

int realtable_memusage(Value* x)
{
    return sizeof(Value)+sizeof(Real);
}

/// Functions on Arrays

kint arraytable_eq(Value* x, Value* y)
{
    return (x->getArray()->eq(y->getArray()));
}

kint arraytable_cmp(Value* x, Value* y)
{
    int ret = x->getArray()->cmp(y->getArray());
    if (ret<0)
      return -1;
    else if (ret>0)
      return 1;
    else return 0;
}

Value* arraytable_copy(Value* x, map<Value*,Value*>& done)
{
    // if x is already copied, return the copied value
    if (done.find(x)!=done.end()) {
      return done[x];
    }
    Value* copied = new Value(x->getArray()->copy(done),KVT_ARRAY);
    done[x]=copied;
    return copied;
}

Value* arraytable_marshal(VMState* vm,vector<Value*>& done,Value* x, int id)
{
    // Check for circles.
    int idx;
    vector<Value*>::iterator it = done.begin();
    for(idx=0;it!=done.end();++it,++idx) {
      if ((*it)==x) {
          // Already done it, just spit out a reference to it.
          wchar_t buf[20];
          SWPRINTF(buf,20,L"[%d]C[%d]",id,idx);
          return new Value(new String(buf),KVT_STRING);
      }
    }
    idx = done.size();
    done.push_back(x);

    Array* v = x->getArray();
    wchar_t buf[34];
    SWPRINTF(buf,34,L"[%d]A[[%d][%d]",id,idx,v->reserved_size());
    String* marray = new String(buf);
    for(int i=0;i<v->size();i++) {
      wchar_t* el = funtable_marshal_aux(vm,done,v->lookup(i),id);
      marray->append(el);
    }
    marray->append(L"]");
    return new Value(marray,KVT_STRING);
}

Value* arraytable_hash(Value* x)
{
    // FIXME: Do this.
    return 0;
}

int arraytable_memusage(Value* x)
{
    int size = sizeof(Value);
    size+=x->getArray()->memusage();
    return size;
}


/// Functions on Unions

kint uniontable_eq(Value* x, Value* y)
{
    return (x->getUnion()->eq(y->getUnion()));
}

kint uniontable_cmp(Value* x, Value* y)
{
    int ret = x->getUnion()->cmp(y->getUnion());
    if (ret<0)
      return -1;
    else if (ret>0)
      return 1;
    else return 0;
}

Value* uniontable_copy(Value* x, map<Value*,Value*>& done)
{
    Value* thisval = new Value(NULL,KVT_UNION);
    done[x] = thisval;
    Value* copied = new Value(x->getUnion()->copy(done),KVT_UNION);
    thisval->setPtr(copied);
    return thisval;
}

Value* uniontable_marshal(VMState* vm,vector<Value*>& done,Value* x, int id)
{
    // Check for circles.
    int idx;
    vector<Value*>::iterator it = done.begin();
    for(idx=0;it!=done.end();++it,++idx) {
      if ((*it)==x) {
          // Already done it, just spit out a reference to it.
          wchar_t buf[20];
          SWPRINTF(buf,20,L"[%d]C[%d]",id,idx);
          return new Value(new String(buf),KVT_STRING);
      }
    }
    idx = done.size();
    done.push_back(x);

    Union *u = x->getUnion();
    wchar_t buf[21];
    SWPRINTF(buf,21,L"[%d]U[[%d]",id,idx);
    String* munion = new String(buf);
    wchar_t utag[50];
    SWPRINTF(utag,50,L"[%d][%d]",U_TAG(u),U_ARITY(u));
    munion->append(utag);

    for(int i=0;i<U_ARITY(u);i++) {
      wchar_t* el = funtable_marshal_aux(vm,done,u->args[i],id);
      munion->append(el);
    }
    munion->append(L"]");
    return new Value(munion,KVT_STRING);
}

Value* uniontable_hash(Value* x)
{
    return 0;
}

int uniontable_memusage(Value* x)
{
    int size = sizeof(Value);
    size+=x->getUnion()->memusage();
    return size;
}

/// Functions on Exceptions

kint exceptiontable_eq(Value* x, Value* y)
{
    return (x->getExcept()->eq(y->getExcept()));
}

kint exceptiontable_cmp(Value* x, Value* y)
{
    kint ret = x->getExcept()->cmp(y->getExcept());
    if (ret<0)
      return -1;
    else if (ret>0)
      return 1;
    else return 0;
}

Value* exceptiontable_copy(Value* x, map<Value*,Value*>& done)
{
    // No point since they're immutable
    return x;
}
Value* exceptiontable_fastcopy(Value* x)
{
    // No point since they're immutable
    return x;
}


Value* exceptiontable_marshal(VMState* vm,vector<Value*>& done,Value* x, int id)
{
    vm->kaya_throw(L"Can't marshal exceptions sensibly",1);
    return new Value(new String(L"<<exception>>"),KVT_STRING);
}

Value* exceptiontable_hash(Value* x)
{
    return 0;
}

int exceptiontable_memusage(Value* x)
{
    int size = sizeof(Value)+sizeof(Exception);
    return size; // FIXME: This is wrong, but not important.
}


Generated by  Doxygen 1.6.0   Back to index