[Tinyos-commits] CVS: tinyos-1.x/tos/lib/VM/languages/motlle/mate/runtime FNseqM.nc, NONE, 1.1 FNbasicM.nc, 1.3, 1.4 FNstringM.nc, 1.2, 1.3

David Gay idgay at users.sourceforge.net
Sun Oct 23 14:09:26 PDT 2005


Update of /cvsroot/tinyos/tinyos-1.x/tos/lib/VM/languages/motlle/mate/runtime
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv19711/runtime

Modified Files:
	FNbasicM.nc FNstringM.nc 
Added Files:
	FNseqM.nc 
Log Message:
marks on values for detecting circular structures
valid_list test
sequence functions (incl. for-each)
frames with attached (nesC) code
consequent revamp of pc->opcode mapping
still needs: testing. revamp of opmhandler4 (to just opmhandler)
PC now indicates special instructions for pc=0 (opmhandler), pc=1 (halt),
  pc=2 (execute frame code)


--- NEW FILE: FNseqM.nc ---
module FNseqM {
  provides {
    //interface MateBytecode as Map;
    interface MateBytecode as ForEach;
    interface MateBytecode as Vector2List;
    interface MateBytecode as List2Vector;
    interface MateBytecode as String2List;
    interface MateBytecode as List2String;
    interface MateBytecode as Length;
    interface MotlleFrame as MapFrame;
  }
  uses {
    interface MotlleGC as GC;
    interface MotlleStack as S;
    interface MotlleTypes as T;
    interface MateError as E;
  }
}
implementation {

  mvalue make_list(msize len) {
    msize i;
    mvalue result = call T.nil();

    for (i = 0; i < len; i++)
      result = call T.make_pair(call T.alloc_list(call T.nil(), result));

    return result;
  }

  bool valid_list(MateContext *context, mvalue l, msize *len) {
    bool ok = call T.valid_list(l, len);

    if (!ok)
      call E.error(context, MOTLLE_ERROR_BAD_VALUE);
    
    return ok;
  }

  //FN vector->list: v -> l. Convert vector to a list.
  command result_t Vector2List.execute(uint8_t instr, MateContext* context) {
    mvalue x = call S.pop(context, 1);

    if (call T.vectorp(x))
      {
	msize len = call T.vector_length(call T.vector(x)), i;
	mvalue result;

	/* Make n element list, then fill it in (we do this to avoid
	   constantly protecting/unprotecting and accessing x) */
	GCPRO1(x);
	result = make_list(len);
	GCPOP1(x);

	if (result)
	  {
	    vvector v = call T.vector(x);
	    mvalue scan = result;

	    for (i = 0; i < len; i++)
	      {
		vpair p = call T.pair(scan);

		p->car = v->data[i];
		scan = p->cdr;
	      }
	    call S.qpush(context, result);
	  }
      }
    else
      call E.error(context, MOTLLE_ERROR_BAD_TYPE);

    return SUCCESS;
  }

  command uint8_t Vector2List.byteLength() {
    return 1;
  }

  //FN string->list: v -> l. Convert string to a list.
  command result_t String2List.execute(uint8_t instr, MateContext* context) {
    mvalue x = call S.pop(context, 1);

    if (call T.stringp(x))
      {
	msize len = call T.string_length(call T.string(x)), i;
	mvalue result;
	
	/* Make n element list, then fill it in (we do this to avoid
	   constantly protecting/unprotecting and accessing x) */
	GCPRO1(x);
	result = make_list(len);
	GCPOP1(x);

	if (result)
	  {
	    vstring s = call T.string(x);
	    mvalue scan = result;

	    for (i = 0; i < len; i++)
	      {
		vpair p = call T.pair(scan);

		p->car = call T.make_int(s->data[i]);
		scan = p->cdr;
	      }
	    call S.qpush(context, result);
	  }
      }
    else
      call E.error(context, MOTLLE_ERROR_BAD_TYPE);

    return SUCCESS;
  }

  command uint8_t String2List.byteLength() {
    return 1;
  }

  //FN list->vector: l -> v. Convert list to vector.
  command result_t List2Vector.execute(uint8_t instr, MateContext* context) {
    mvalue x = call S.pop(context, 1);
    msize len, i;
    vvector v;

    if (valid_list(context, x, &len))
      {
	GCPRO1(x);
	v = call T.alloc_vector(len);
	GCPOP1(x);

	if (v)
	  {
	    for (i = 0; i < len; i++)
	      {
		vpair p = call T.pair(x);

		v->data[i] = p->car;
		x = p->cdr;
	      }
	    call S.qpush(context, call T.make_vector(v));
	  }
      }

    return SUCCESS;
  }

  command uint8_t List2Vector.byteLength() {
    return 1;
  }

  //FN list->string: l -> v. Convert list to string.
  command result_t List2String.execute(uint8_t instr, MateContext* context) {
    mvalue x = call S.pop(context, 1);
    msize len, i;
    vstring s;

    if (valid_list(context, x, &len))
      {
	GCPRO1(x);
	s = call T.alloc_string(len);
	GCPOP1(x);

	if (s)
	  {
	    for (i = 0; i < len; i++)
	      {
		vpair p = call T.pair(x);

		s->data[i] = call T.intv(p->car);
		x = p->cdr;
	      }
	    call S.qpush(context, call T.make_string(s));
	  }
      }

    return SUCCESS;
  }

  command uint8_t List2String.byteLength() {
    return 1;
  }

  //FN length: x -> n. Return length of vector or string
  command result_t Length.execute(uint8_t instr, MateContext* context) {
    mvalue x = call S.pop(context, 1);

    if (call T.vectorp(x))
      call S.qpush(context, call T.make_int(call T.vector_length(call T.vector(x))));
    else if (call T.stringp(x))
      call S.qpush(context, call T.make_int(call T.string_length(call T.string(x))));
    else
      call E.error(context, MOTLLE_ERROR_BAD_TYPE);
    return SUCCESS;
  }

  command uint8_t Length.byteLength() {
    return 1;
  }

  struct map_frame {
    msize idx, len;
    uint8_t nargs;
    uint16_t retpc;
    void *sp;
  };

  bool map_length(MateContext *context, uint8_t i, msize *len) {
    mvalue x = call S.get(context, i);

    if (call T.vectorp(x))
      {
	*len = call T.vector_length(call T.vector(x));
	return TRUE;
      }
    else if (call T.stringp(x))
      {
	call T.string_length(call T.string(x));
	return TRUE;
      }
    else
      return valid_list(context, x, len);
  }

  mvalue map_arg(void *sp, msize idx, uint8_t i) {
    mvalue arg = call S.getOtherFrame(sp, i);

    if (call T.vectorp(x))
      return (call T.vector(x))->data[idx];
    else if (call T.stringp(x))
      return call T.make_int((call T.string(x))->data[idx]);
    else
      {
	vpair p = call T.pair(x);

	call S.putOtherFrame(sp, i, p->cdr);
	
	return p->car;
      }
  }

  command void MapFrame.execute(MateContext *context, void *vframe) {
    struct map_frame *frame = vframe;
    uint8_t i, nargs = map_frame->nargs;

    if (map_frame->idx != 0)
      call S.pop(context, 1); // get rid of the old result

    if (map_frame->idx++ == len)
      {
	/* Done. Get rid of the frame and old arguments. */
	context->pc = frame->retpc;
	call S.pop_frame(context, sizeof(struct map_frame));
	call S.pop(context, nargs + 1);
	call S.qpush(context, call T.make_int(42));
	return;
      }

    if (call S.reserve(context, (nargs + 1) * sizeof(svalue)))
      {
	for (i = 0; i < nargs; i++)
	  call S.qpush(context, map_arg(map_frame->sp, idx, i));
	call S.qpush(context, call S.getOtherFrame(map_frame->sp, nargs));
	call Exec.execute(OP_MEXEC4 + nargs, context);
      }
  }

  command msize MapFrame.gc_forward(MateContext *context, void *vframe, uint8_t *lfp, uint8_t *lsp) {
    return sizeof(struct map_frame);
  }

  void push_map_frame(MateContext *context, uint8_t nargs, msize len) {
    struct map_frame *map_frame;
    void *map_sp = call S.sp(context);

    frame = call S.alloc_frame(context, MOTLLE_MAP_FRAME,
			       sizeof(struct map_frame));
    if (frame)
      {
	frame->idx = 0;
	frame->len = len;
	frame->nargs = nargs;
	frame->retpc = context->pc;
	frame->sp = map_sp;
	context->pc = 2;
      }
  }

  bool check_map_args(MateContext *context, uint8_t nargs, msize *len) {
    bool first = TRUE;
    uint8_t i;

    /* Check min/max args */
    if (nargs <= 1 || --nargs >= 16)
      {
	call E.error(context, MOTLLE_ERROR_BAD_VALUE);
	return FALSE;
      }

    mvalue fn = call S.get(context, nargs);
    if (!call T.functionp(fn))
      {
	call E.error(context, MOTLLE_ERROR_BAD_VALUE);
	return FALSE;
      }

    /* Check that all sequences are of the same lengths */
    for (i = 0; i < nargs; i++)
      {
	if (!map_length(context, i, &nlen))
	  return FALSE;

	if (first)
	  *len = nlen;
	else if (*len != nlen)
	  {
	    call E.error(context, MOTLLE_ERROR_BAD_VALUE);
	    return FALSE;
	  }
      }

    return TRUE;
  }

  //FN for-each: fn x1 ... -> x.: apply fn to the n-tuple formed by taking
  //   one element from each xi list/vector/string, in order.
  //   Each xi must have the same length. The result is undefined.
  command result_t ForEach.execute(uint8_t nargs, MateContext* context) {
    msize len = 0, idx;

    if (check_map_args(context, nargs, &len))
      push_map_frame(context, nargs, len);

    return SUCCESS;
  }

  command uint8_t ForEach.byteLength() {
    return 1;
  }

#if 0
  //FN map: fn x1 ... -> x.: apply fn to the n-tuple formed by taking
  //   one element from each xi list/vector/string.
  //   Each xi must have the same length. The result is the result of
  //   the calls to fn.
  command result_t Map.execute(uint8_t instr, MateContext* context) {
    return SUCCESS;
  }

  command uint8_t Map.byteLength() {
    return 1;
  }
#endif
}
  


Index: FNbasicM.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-1.x/tos/lib/VM/languages/motlle/mate/runtime/FNbasicM.nc,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** FNbasicM.nc	23 Oct 2005 17:21:44 -0000	1.3
--- FNbasicM.nc	23 Oct 2005 21:09:24 -0000	1.4
***************
*** 2,5 ****
--- 2,6 ----
    provides {
      interface MateBytecode as FunctionP;
+     interface MateBytecode as SymbolP;
      interface MateBytecode as Apply;
      interface MateBytecode as Error;
***************
*** 79,82 ****
--- 80,94 ----
    }
  
+   //FN symbol?: x -> b. TRUE if x is a symbol
+   command result_t SymbolP.execute(uint8_t instr, MateContext* context) {
+     mvalue x = call S.pop(context, 1);
+     call S.qpush(context, call T.make_bool(call T.symbolp(x)));
+     return SUCCESS;
+   }
+ 
+   command uint8_t SymbolP.byteLength() {
+     return 1;
+   }
+ 
    //FN garbage_collect: -> . Does a forced garbage collection
    //The constants below are here for lack of a good place.

Index: FNstringM.nc
===================================================================
RCS file: /cvsroot/tinyos/tinyos-1.x/tos/lib/VM/languages/motlle/mate/runtime/FNstringM.nc,v
retrieving revision 1.2
retrieving revision 1.3
diff -C2 -d -r1.2 -r1.3
*** FNstringM.nc	30 Nov 2004 18:52:43 -0000	1.2
--- FNstringM.nc	23 Oct 2005 21:09:24 -0000	1.3
***************
*** 80,82 ****
--- 80,100 ----
      return 1;
    }
+ 
+   //FN string: n1 ... -> v. Returns a string of its character arguments
+   command result_t String.execute(uint8_t nargs, MateContext* context) {
+     vstring s = call T.alloc_string(nargs);
+ 
+     if (s)
+       {
+ 	while (nargs-- > 0)
+ 	  s->data[nargs] = call T.intv(call S.pop(context, 1));
+ 	call S.push(context, call T.make_string(s));
+       }
+ 
+     return SUCCESS;
+   }
+ 
+   command uint8_t String.byteLength() {
+     return 1;
+   }
  }



More information about the Tinyos-commits mailing list