#include "m.h" #define aij SCALAR(a) ? VAL(a) : (a->type == STRING ? STR(a)[j] : A(i,j) ) #define STACKSIZE 8192 #define FRAMESIZE 1024 Symbolptr stack[STACKSIZE]; /* data stack */ Symbolptr *sp = stack; /* next free spot for push() */ Symbolptr *frame[FRAMESIZE]; /* frame stack */ Symbolptr **fp = frame; /* next free spot for fpush() */ void local_push( void) { int offset = (int) *pc++; push( *(ftop() + offset) ); } void sympush( void) /* push symbol onto the stack */ { Symbolptr p = i2d(*pc++); push(p); } void swap( void) { Symbolptr a, b; a = pop(); b = pop(); push(a); push(b); } void fpush( void) { if( fp >= frame + FRAMESIZE) error("frame overflow in fpush()",""); *fp++ = sp; } void fpop( void) { if( fp <= frame) error("frame underflow in fpop()",""); sp = *--fp; } Symbolptr *ftop( void) { if( fp <= frame) error("frame underflow in ftop()",""); return *(fp-1); } void push( Symbolptr a) { if( sp >= stack + STACKSIZE) error("stack overflow in push()",""); *sp++ = a; #ifdef DEBUG if( stack_debug) display( a, "push: "); #endif } Symbolptr pop( void) { if( sp <= ftop()) error("stack underflow in pop()",""); --sp; #ifdef DEBUG if( stack_debug) display( *sp, "pop: "); #endif return *sp; } void npop( int n) { sp -= n; #ifdef DEBUG if( stack_debug) dprint("npop: n = %d\n", n); #endif if( sp < ftop()) error("stack underflow in npop()",""); } void matpop( void) { Symbolptr v, a; Symbolptr *savesp, *start; int i, j, m, n = 0, rows, cols; a = pop(); n_check(a,"matpop()"); savesp = sp; sp = start = sp - (int) VAL(a); #ifdef DEBUG if( stack_debug) dprint("matpop(): count = %d\n", (int) VAL(a)); #endif if( sp >= stack + STACKSIZE) error("stack overflow in matpop()",""); else if( sp < ftop()) error("stack underflow in matpop()",""); rows = cols = 0; while( sp < savesp) { /* get rows & cols */ m = n = 0; while( sp < savesp && *sp != &rowend) { check(a = *sp); if( m == 0) { m = ROWS(a); n = COLS(a); } else if( m != ROWS(a)) error("mismatched row sizes in matrix",""); else n += COLS(a); ++sp; } if( rows == 0) { rows = m; cols = n; } else if( cols != n) error("mismatched column sizes in matrix",""); else rows += m; ++sp; } #ifdef DEBUG if( stack_debug) dprint("matpop: rows = %d, cols = %d\n", rows, cols); #endif v = m_create( rows, cols); sp = start; rows = cols = 0; while( sp < savesp) { m = rows; while( sp < savesp && *sp != &rowend) { a = *sp; for( i = 0, m = rows; i < ROWS(a); ++i, ++m) for( j = 0, n = cols; j < COLS(a); ++j, ++n) if( SCALAR(v)) VAL(v) = aij; else V(m,n) = aij; cols = n; ++sp; } rows = m; cols = 0; ++sp; } sp = start; push(v); } #ifdef DEBUG void s_dump( void) { Symbolptr *s; dprint("stack: %d elements\n", sp-stack); for( s = stack; s < sp; ++s) display( *s, ""); } #endif