Example #1
0
File: file.c Project: perl11/potion
/**\memberof PNFile
 \c "write" a binary representation of obj to the file handle.
 \param obj PNString, PNBytes, PNInteger (long or double), PNBoolean (char 0 or 1)
 \return PNInteger written bytes or PN_NIL */
PN potion_file_write(Potion *P, PN cl, pn_file self, PN obj) {
  long len = 0;
  char *ptr = NULL;
  union { double d; long l; char c; } tmp;
  //TODO: maybe extract ptr+len to seperate function
  if (!PN_IS_PTR(obj)) {
    if (!obj) return PN_NIL; //silent
    else if (PN_IS_INT(obj)) {
      tmp.l = PN_NUM(obj); len = sizeof(tmp); ptr = (char *)&tmp.l;
    }
    else if (PN_IS_BOOL(obj)) {
      tmp.c = (obj == PN_TRUE) ? 1 : 0; len = 1; ptr = (char *)&tmp.c;
    }
    else {
      assert(0 && "Invalid primitive type");
    }
  } else {
    switch (PN_TYPE(obj)) {
      case PN_TSTRING: len = PN_STR_LEN(obj); ptr = PN_STR_PTR(obj); break;
      case PN_TBYTES:  len = potion_send(obj, PN_STR("length")); ptr = PN_STR_PTR(obj); break;
      case PN_TNUMBER: {
        tmp.d = PN_DBL(obj); len = sizeof(tmp); ptr = (char *)&tmp.d;
        break;
      }
      default: return potion_type_error(P, obj);
    }
  }
  int r = write(self->fd, ptr, len);
  if (r == -1)
    return potion_io_error(P, "write");
  return PN_NUM(r);
}
Example #2
0
PN potion_error(Potion *P, PN msg, long lineno, long charno, PN excerpt) {
  struct PNError *e = PN_ALLOC(PN_TERROR, struct PNError);
  e->message = msg;
  e->line = PN_NUM(lineno);
  e->chr = PN_NUM(charno);
  e->excerpt = excerpt;
  return (PN)e;
}
Example #3
0
PN potion_gc_fixed(Potion *P, PN cl, PN self)
{
  int total = 0;
  if (P->mem->protect != NULL)
    total += (char *)P->mem->protect - (char *)P->mem;
  return PN_NUM(total);
}
Example #4
0
void potion_test_int3(CuTest *T) {
  PN neg = PN_NUM(-4343);
  CuAssert(T, "negative numbers invalid", PN_INT(neg) == -4343);
  CuAssert(T, "negative not a number", PN_IS_INT(neg));
  CuAssert(T, "negative is a ref", !PN_IS_PTR(neg));
  CuAssert(T, "negative bad add",
    -3853 == PN_INT(potion_send(neg, potion_str(P, "+"), num)));
}
Example #5
0
void potion_test_int2(CuTest *T) {
  PN pos = PN_NUM(10891);
  CuAssert(T, "positive numbers invalid", PN_INT(pos) == 10891);
  CuAssert(T, "positive not a number", PN_IS_INT(pos));
  CuAssert(T, "positive is a ref", !PN_IS_PTR(pos));
  CuAssert(T, "positive bad add",
    11381 == PN_INT(potion_send(pos, potion_str(P, "+"), num)));
}
Example #6
0
PN potion_file_write(Potion *P, PN cl, pn_file self, PN str) {
  int r = write(self->fd, PN_STR_PTR(str), PN_STR_LEN(str));
  if (r == -1) {
    perror("write");
    // TODO: error
    return PN_NIL;
  }
  return PN_NUM(r);
}
Example #7
0
PN potion_gc_reserved(Potion *P, PN cl, PN self)
{
  int total = (char *)P->mem->birth_hi - (char *)P->mem->birth_lo;
  if (P->mem != P->mem->birth_lo)
    total += (char *)P->mem->protect - (char *)P->mem;
  if (P->mem->old_lo != NULL)
    total += (char *)P->mem->old_hi - (char *)P->mem->old_lo;
  return PN_NUM(total);
}
Example #8
0
PN potion_file_read(Potion *P, PN cl, pn_file self, PN n) {
  n = PN_INT(n);
  char buf[n];
  int r = read(self->fd, buf, n);
  if (r == -1) {
    perror("read");
    // TODO: error
    return PN_NUM(-1);
  } else if (r == 0) {
    return PN_NIL;
  }
  return potion_byte_str2(P, buf, r);
}
Example #9
0
void potion_test_eval(CuTest *T) {
  PN add, num;
  PN_F addfn;

#if POTION_JIT
  long flags = P->flags;
  if (P->flags & EXEC_JIT) P->flags = (Potion_Flags)((int)P->flags - EXEC_JIT);
#endif
  add = potion_eval(P, potion_str(P, "(x, y): x + y."));
  addfn = PN_CLOSURE_F(add); // c callback
  CuAssertPtrNotNull(T, addfn);
  num = addfn(P, add, 0, PN_NUM(3), PN_NUM(5));
  CuAssertIntEquals(T, "calling closure as c func", 8, PN_INT(num));

  add = potion_eval(P, potion_str(P, "(x=N|y=N): x + y."));
  addfn = PN_CLOSURE_F(add);
  num = addfn(P, add, 0, PN_NUM(3), PN_NUM(5));
  CuAssertIntEquals(T, "calling closure as c func (opt)", 8, PN_INT(num));
  num = addfn(P, add, 1, PN_NUM(3));
  CuAssertIntEquals(T, "optional num = 0", 3, PN_INT(num));

  add = potion_eval(P, potion_str(P, "(x=N,y:=1): x + y."));
  addfn = PN_CLOSURE_F(add);
  num = addfn(P, add, 2, PN_NUM(3), PN_NUM(5));
  CuAssertIntEquals(T, "calling closure as c func (default)", 8, PN_INT(num));
  num = addfn(P, add, 1, PN_NUM(3));
  CuAssertIntEquals(T, "default num = 1", 4, PN_INT(num));

#if POTION_JIT
  P->flags = (Potion_Flags)flags; //restore JIT
  add = potion_eval(P, potion_str(P, "(x, y): x + y."));
  addfn = PN_CLOSURE_F(add); // c callback
  CuAssertPtrNotNull(T, addfn);
  num = addfn(P, add, 0, PN_NUM(3), PN_NUM(5));
  CuAssertIntEquals(T, "calling closure as c func (jit)", 8, PN_INT(num));

#ifdef DEBUG
  //P->flags += DEBUG_COMPILE + DEBUG_JIT;
#endif
  add = potion_eval(P, potion_str(P, "(x=N|y=N): x + y."));
  addfn = PN_CLOSURE_F(add);
  num = addfn(P, add, 0, PN_NUM(3), PN_NUM(5));
  CuAssertIntEquals(T, "calling closure as c func (jit+opt)", 8, PN_INT(num));
  //hard to make this work, would slow it down
  //num = addfn(P, add, 0, PN_NUM(3));
  //CuAssertIntEquals(T, "optional num = 0 (jit)", 3, PN_INT(num));

  add = potion_eval(P, potion_str(P, "(x=N|y:=1): x + y."));
  addfn = PN_CLOSURE_F(add);
  num = addfn(P, add, 0, PN_NUM(3), PN_NUM(5));
  CuAssertIntEquals(T, "calling closure as c func (jit+default)", 8, PN_INT(num));
  //num = addfn(P, add, 0, PN_NUM(3));
  //CuAssertIntEquals(T, "default num = 1 (jit)", 4, PN_INT(num));
#endif

}
Example #10
0
//
// potion-test.c
// tests of the Potion C api
//
// (c) 2008 why the lucky stiff, the freelance professor
// (c) 2013 perl11 org
//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include "potion.h"
#include "internal.h"
#include "CuTest.h"

PN num = PN_NUM(490);
Potion *P;

void potion_test_nil(CuTest *T) {
  CuAssert(T, "nil isn't a nil type", PN_TYPE(PN_NIL) == PN_TNIL);
  CuAssert(T, "nil is a ref", !PN_IS_PTR(PN_NIL));
  CuAssert(T, "nil nil? is false",
    PN_TRUE == potion_send(PN_NIL, potion_str(P, "nil?")));
}

void potion_test_bool(CuTest *T) {
  CuAssert(T, "true isn't a bool type", PN_TYPE(PN_TRUE) == PN_TBOOLEAN);
  CuAssert(T, "true is a ref", !PN_IS_PTR(PN_TRUE));
  CuAssert(T, "false isn't a bool type", PN_TYPE(PN_FALSE) == PN_TBOOLEAN);
  CuAssert(T, "false is a ref", !PN_IS_PTR(PN_FALSE));
}