Stat NewStatOrExpr(CodeState * cs, UInt type, UInt size, UInt line)
{
Stat stat; // result
// this is where the new statement goes
stat = cs->OffsBody + sizeof(StatHeader);
// increase the offset
cs->OffsBody =
stat + ((size + sizeof(Stat) - 1) / sizeof(Stat)) * sizeof(Stat);
// make certain that the current body bag is large enough
Obj body = cs->currBody;
UInt bodySize = SIZE_BAG(body); if (bodySize == 0)
bodySize = cs->OffsBody; while (bodySize < cs->OffsBody)
bodySize *= 2;
ResizeBag(body, bodySize);
// enter type and size
StatHeader * header = STAT_HEADER(cs, stat);
header->line = line;
header->size = size; // check size fits inside header if (header->size != size) {
ErrorQuit("function too large for parser", 0, 0);
}
header->type = type;
RegisterStatWithHook(GET_GAPNAMEID_BODY(cs->currBody), line, type); // return the new statement return stat;
}
void PushStat (
Stat stat )
{ // there must be a stack, it must not be underfull or overfull
GAP_ASSERT(CS(StackStat) != 0);
GAP_ASSERT(0 <= CS(CountStat));
GAP_ASSERT(CS(CountStat) <= CapacityStatStack());
GAP_ASSERT( stat != 0 );
// count up and put the statement onto the stack if (CS(CountStat) == CapacityStatStack()) {
ResizeBag(CS(StackStat), (2 * CS(CountStat) + 1) * sizeof(Stat));
}
// put
Stat * data = (Stat *)PTR_BAG(CS(StackStat)) + 1;
data[CS(CountStat)] = stat;
CS(CountStat)++;
}
static Stat PopStat ( void )
{
Stat stat;
// there must be a stack, it must not be underfull/empty or overfull
GAP_ASSERT(CS(StackStat) != 0);
GAP_ASSERT(1 <= CS(CountStat));
GAP_ASSERT(CS(CountStat) <= CapacityStatStack());
// get the top statement from the stack, and count down
CS(CountStat)--;
Stat * data = (Stat *)PTR_BAG(CS(StackStat)) + 1;
stat = data[CS(CountStat)];
// return the popped statement return stat;
}
static Stat PopSeqStat(CodeState * cs, UInt nr)
{
Stat body; // sequence, result
Stat stat; // single statement
UInt i; // loop variable
if (nr == 0 ) {
body = NewStat(cs, STAT_EMPTY, 0);
} // special case for a single statement elseif ( nr == 1 ) {
body = PopStat();
}
// general case else {
// allocate the sequence if ( 2 <= nr && nr <= 7 ) {
body = NewStat(cs, STAT_SEQ_STAT + (nr - 1), nr * sizeof(Stat));
} else {
body = NewStat(cs, STAT_SEQ_STAT, nr * sizeof(Stat));
}
// enter the statements into the sequence for ( i = nr; 1 <= i; i-- ) {
stat = PopStat();
WRITE_STAT(cs, body, i - 1, stat);
}
}
// return the sequence return body;
}
staticinline Stat
PopLoopStat(CodeState * cs, UInt baseType, UInt extra, UInt nr)
{ // fix up the case of no statements if (0 == nr) {
PushStat(NewStat(cs, STAT_EMPTY, 0));
nr = 1;
}
// collect the statements into a statement sequence if necessary elseif (3 < nr) {
PushStat(PopSeqStat(cs, nr));
nr = 1;
}
// allocate the compound statement
Stat stat = NewStat(cs, baseType + (nr - 1),
extra * sizeof(Expr) + nr * sizeof(Stat));
// enter the statements for (UInt i = nr; 1 <= i; i--) {
Stat stat1 = PopStat();
WRITE_STAT(cs, stat, i + extra - 1, stat1);
}
staticvoid PushExpr(Expr expr)
{ // there must be a stack, it must not be underfull or overfull
GAP_ASSERT(CS(StackExpr) != 0);
GAP_ASSERT(0 <= CS(CountExpr));
GAP_ASSERT(CS(CountExpr) <= CapacityStackExpr());
GAP_ASSERT( expr != 0 );
// count up and put the expression onto the stack if (CS(CountExpr) == CapacityStackExpr()) {
ResizeBag(CS(StackExpr), (2 * CS(CountExpr) + 1) * sizeof(Expr));
}
// there must be a stack, it must not be underfull/empty or overfull
GAP_ASSERT(CS(StackExpr) != 0);
GAP_ASSERT(1 <= CS(CountExpr));
GAP_ASSERT(CS(CountExpr) <= CapacityStackExpr());
// get the top expression from the stack, and count down
CS(CountExpr)--;
Expr * data = (Expr *)PTR_BAG(CS(StackExpr)) + 1;
expr = data[CS(CountExpr)];
// give it a body
body = NewBag( T_BODY, 1024*sizeof(Stat) );
SET_BODY_FUNC( fexp, body );
CHANGED_BAG( fexp );
// record where we are reading from if (gapnameid)
SET_GAPNAMEID_BODY(body, gapnameid);
SET_STARTLINE_BODY(body, startLine);
cs->OffsBody = sizeof(BodyHeader);
// give it an environment
SET_ENVI_FUNC(fexp, cs->CodeLVars);
CHANGED_BAG(fexp);
MakeHighVars(cs->CodeLVars);
// switch to this function if (narg < 0)
narg = -narg;
// create new lvars, linking to the previous lvars
lvars = NewLVarsBag(narg + nloc);
hdr = (LVarsHeader *)ADDR_OBJ(lvars);
hdr->stat = 0;
hdr->func = fexp;
hdr->parent = cs->CodeLVars;
// ... and from now on put generated code into the new lvars / new body
cs->CodeLVars = lvars;
cs->currBody = body;
// allocate the top level statement sequence
NewStat(cs, STAT_SEQ_STAT, 8 * sizeof(Stat));
}
Expr CodeFuncExprEnd(CodeState * cs, UInt nr, BOOL pushExpr, Int endLine)
{
Expr expr; // function expression, result
Stat stat1; // single statement of body
Obj fexp; // function expression bag
UInt len; // length of func. expr. list
UInt i; // loop variable
// get the function expression
fexp = FUNC_LVARS(cs->CodeLVars);
// get the body of the function // push an additional return-void-statement if necessary // the function interpreters depend on each function ``returning'' if ( nr == 0 ) {
CodeReturnVoid(cs);
nr++;
} else {
stat1 = PopStat();
PushStat(stat1); // If we code a function where the body is already packed into nested // sequence statements, e.g., from reading in a syntax tree, we need // to find the last `real` statement of the last innermost sequence // statement to determine if there is already a return or not. while (STAT_SEQ_STAT <= TNUM_STAT_OR_EXPR(cs, stat1) &&
TNUM_STAT_OR_EXPR(cs, stat1) <= STAT_SEQ_STAT7) {
UInt size = STAT_HEADER(cs, stat1)->size / sizeof(Stat); // stat1 = READ_STAT(stat1, size - 1);
stat1 = ADDR_STAT(cs, stat1)[size - 1];
} if (TNUM_STAT_OR_EXPR(cs, stat1) != STAT_RETURN_VOID &&
TNUM_STAT_OR_EXPR(cs, stat1) != STAT_RETURN_OBJ) {
CodeReturnVoidWhichIsNotProfiled(cs);
nr++;
}
}
// if the body is a long sequence, pack the other statements if ( 7 < nr ) {
stat1 = PopSeqStat(cs, nr - 6);
PushStat( stat1 );
nr = 7;
}
// stuff the first statements into the first statement sequence // Making sure to preserve the line number and file name
StatHeader * header = STAT_HEADER(cs, OFFSET_FIRST_STAT);
header->size = nr*sizeof(Stat);
header->type = STAT_SEQ_STAT+nr-1; for ( i = 1; i <= nr; i++ ) {
stat1 = PopStat();
WRITE_STAT(cs, OFFSET_FIRST_STAT, nr - i, stat1);
}
// make the body values list (if any) immutable
Obj values = VALUES_BODY(cs->currBody); if (values)
MakeImmutable(values);
// make the body smaller
ResizeBag(BODY_FUNC(fexp), cs->OffsBody);
SET_ENDLINE_BODY(BODY_FUNC(fexp), endLine);
// switch back to the previous function
cs->CodeLVars = ENVI_FUNC(fexp);
cs->currBody = BODY_FUNC(FUNC_LVARS(cs->CodeLVars));
// restore the remembered offset
PopOffsBody(cs);
// if this was inside another function definition, make the expression // and store it in the function expression list of the outer function if (STATE(CurrLVars) != cs->CodeLVars) {
len = AddValueToBody(cs, fexp);
expr = NewExpr(cs, EXPR_FUNC, sizeof(Expr));
WRITE_EXPR(cs, expr, 0, len); if (pushExpr) {
PushExpr(expr);
} return expr;
}
// otherwise, make the function and store it in 'cs->CodeResult' else {
cs->CodeResult = MakeFunction(fexp);
}
Int CodeIfBeginBody(CodeState * cs)
{ // get and check the condition
Expr cond = PopExpr();
// if the condition is 'false', ignore the body if (TNUM_STAT_OR_EXPR(cs, cond) == EXPR_FALSE) { return1; // signal interpreter to set IntrIgnoring to 1
} else { // put the condition expression back on the stack
PushExpr(cond); return0;
}
}
Int CodeIfEndBody(CodeState * cs, UInt nr)
{ // collect the statements in a statement sequence if necessary
PushStat(PopSeqStat(cs, nr));
// get and check the condition
Expr cond = PopExpr();
PushExpr(cond);
// if the condition is 'true', signal interpreter to set IntrIgnoring to // 1, so that other branches of the if-statement are ignored return TNUM_STAT_OR_EXPR(cs, cond) == EXPR_TRUE;
}
void CodeIfEnd(CodeState * cs, UInt nr)
{
Stat stat; // if-statement, result
Expr cond; // condition of a branch
UInt hase; // has else branch
UInt i; // loop variable
// if all conditions were false, the if-statement is an empty statement if (nr == 0) {
PushStat(NewStat(cs, STAT_EMPTY, 0)); return;
}
// peek at the last condition
cond = PopExpr();
hase = (TNUM_STAT_OR_EXPR(cs, cond) == EXPR_TRUE);
PushExpr(cond);
// optimize 'if true then BODY; fi;' to just 'BODY;' if (nr == 1 && hase) { // drop the condition expression, leave the body statement
PopExpr(); return;
}
// allocate the if-statement if ( nr == 1 ) {
stat = NewStat(cs, STAT_IF, nr * (sizeof(Expr) + sizeof(Stat)));
} elseif ( nr == 2 && hase ) {
stat = NewStat(cs, STAT_IF_ELSE, nr * (sizeof(Expr) + sizeof(Stat)));
} elseif ( ! hase ) {
stat = NewStat(cs, STAT_IF_ELIF, nr * (sizeof(Expr) + sizeof(Stat)));
} else {
stat = NewStat(cs, STAT_IF_ELIF_ELSE,
nr * (sizeof(Expr) + sizeof(Stat)));
}
// enter the branches for ( i = nr; 1 <= i; i-- ) {
Stat body = PopStat();
cond = PopExpr();
WRITE_STAT(cs, stat, 2 * (i - 1), cond);
WRITE_STAT(cs, stat, 2 * (i - 1) + 1, body);
}
void CodeForEndBody(CodeState * cs, UInt nr)
{
Stat stat; // for-statement, result
UInt type; // type of for-statement
Expr var; // variable
Expr list; // list
// get the list expression
list = PopExpr();
// get the variable reference
var = PopExpr();
type = STAT_FOR;
// select the type of the for-statement if (TNUM_STAT_OR_EXPR(cs, list) == EXPR_RANGE) {
StatHeader * hdr = STAT_HEADER(cs, list); if (hdr->size == 2 * sizeof(Expr) && IS_REF_LVAR(var)) {
type = STAT_FOR_RANGE;
}
}
// allocate the for-statement
stat = PopLoopStat(cs, type, 2, nr);
// enter the list expression
WRITE_STAT(cs, stat, 1, list);
// enter the variable reference
WRITE_STAT(cs, stat, 0, var);
void CodeAtomicEndBody(CodeState * cs, UInt nrstats)
{ #ifdef HPCGAP
Stat stat; // atomic-statement, result
Stat stat1; // single statement of body
UInt i; // loop variable
UInt nrexprs;
Expr e,qual;
// collect the statements into a statement sequence
stat1 = PopSeqStat(cs, nrstats);
nrexprs = INT_INTEXPR(PopExpr());
// allocate the atomic-statement
stat =
NewStat(cs, STAT_ATOMIC, sizeof(Stat) + nrexprs * 2 * sizeof(Stat));
// enter the statement sequence
WRITE_STAT(cs, stat, 0, stat1);
// enter the expressions for ( i = 2*nrexprs; 1 <= i; i -= 2 ) {
e = PopExpr();
qual = PopExpr();
WRITE_STAT(cs, stat, i, e);
WRITE_STAT(cs, stat, i - 1, qual);
}
// push the atomic-statement
PushStat( stat ); #else
Stat stat = PopSeqStat(cs, nrstats);
UInt nrexprs = INT_INTEXPR(PopExpr()); while (nrexprs--) {
PopExpr();
PopExpr();
}
PushStat( stat ); #endif
}
void CodeRepeatEndBody(CodeState * cs, UInt nr)
{ // leave the number of statements in the body on the expression stack
PushExpr( INTEXPR_INT(nr) );
}
void CodeRepeatEnd(CodeState * cs)
{
Stat stat; // repeat-statement, result
UInt nr; // number of statements in body
Expr cond; // condition
Expr tmp; // temporary
// get the condition
cond = PopExpr();
// get the number of statements in the body // 'CodeUntil' left this number on the expression stack (hack)
tmp = PopExpr();
nr = INT_INTEXPR( tmp );
// allocate the repeat-statement
stat = PopLoopStat(cs, STAT_REPEAT, 1, nr);
// enter the condition
WRITE_STAT(cs, stat, 0, cond);
// push the repeat-statement
PushStat( stat );
}
/**************************************************************************** ** *FCodeBreak()....................codebreak-statement ** **'CodeBreak'istheactiontocodeabreak-statement.Itiscalledwhen **thereaderencountersa'break;'.
*/ void CodeBreak(CodeState * cs)
{
Stat stat; // break-statement, result
// allocate the break-statement
stat = NewStat(cs, STAT_BREAK, 0 * sizeof(Expr));
// push the break-statement
PushStat( stat );
}
/**************************************************************************** ** *FCodeContinue().................codecontinue-statement ** **'CodeContinue'istheactiontocodeacontinue-statement.Itiscalled **whenthereaderencountersa'continue;'.
*/ void CodeContinue(CodeState * cs)
{
Stat stat; // continue-statement, result
// allocate the continue-statement
stat = NewStat(cs, STAT_CONTINUE, 0 * sizeof(Expr));
// push the continue-statement
PushStat( stat );
}
/**************************************************************************** ** *FCodeUnbList()...............codeunbindoflistposition
*/
void CodeUnbList(CodeState * cs, Int narg)
{
Stat ass; // unbind, result
Expr list; // list expression
Expr pos; // position expression
Int i;
// allocate the unbind
ass = NewStat(cs, STAT_UNB_LIST, (narg + 1) * sizeof(Stat));
// enter the position expressions
for (i = narg; i > 0; i--) {
pos = PopExpr();
WRITE_STAT(cs, ass, i, pos);
}
// enter the list expression
list = PopExpr();
WRITE_STAT(cs, ass, 0, list);
// push the unbind
PushStat( ass );
}
/**************************************************************************** ** *FCodeElmList().................codeselectionofalist *FCodeElmsList()............codemultipleselectionofalist *FCodeElmListLevel(<level>).......codeselectionofseverallists *FCodeElmsListLevel(<level>).codemultipleselectionofseverallists
*/
static void CodeElmListUniv(CodeState * cs, Expr ref, Int narg)
{
Expr list; // list expression
Expr pos; // position expression
Int i;
// enter the position expression
for (i = narg; i > 0; i--) {
pos = PopExpr();
WRITE_EXPR(cs, ref, i, pos);
}
// enter the list expression
list = PopExpr();
WRITE_EXPR(cs, ref, 0, list);
// push the reference
PushExpr( ref );
}
void CodeElmList(CodeState * cs, Int narg)
{
Expr ref; // reference, result
GAP_ASSERT(narg == 1 || narg == 2);
// allocate the reference if (narg == 1)
ref = NewExpr(cs, EXPR_ELM_LIST, 2 * sizeof(Expr));
else // if (narg == 2)
ref = NewExpr(cs, EXPR_ELM_MAT, 3 * sizeof(Expr));
// let'CodeElmListUniv' to the rest
CodeElmListUniv(cs, ref, narg);
}
void CodeElmsList(CodeState * cs)
{
Expr ref; // reference, result
// enter the position expression
for (i = narg; i > 0; i--) {
pos = PopExpr();
WRITE_EXPR(cs, ref, i, pos);
}
// enter the list expression
list = PopExpr();
WRITE_EXPR(cs, ref, 0, list);
// push the isbound
PushExpr( ref );
}
/**************************************************************************** ** *FCodeAssRecName(<rnam>)..........codeassignmenttoarecord *FCodeAssRecExpr()..............codeassignmenttoarecord
*/
void CodeAssRecName(CodeState * cs, UInt rnam)
{
Stat stat; // assignment, result
Expr rec; // record expression
Expr rhsx; // right hand side expression
// allocate the assignment
stat = NewStat(cs, STAT_ASS_REC_NAME, 3 * sizeof(Stat));
// enter the right hand side expression
rhsx = PopExpr();
WRITE_STAT(cs, stat, 2, rhsx);
// enter the name
WRITE_STAT(cs, stat, 1, rnam);
// enter the record expression
rec = PopExpr();
WRITE_STAT(cs, stat, 0, rec);
// push the assignment
PushStat( stat );
}
void CodeAssRecExpr(CodeState * cs)
{
Stat stat; // assignment, result
Expr rec; // record expression
Expr rnam; // name expression
Expr rhsx; // right hand side expression
// allocate the assignment
stat = NewStat(cs, STAT_ASS_REC_EXPR, 3 * sizeof(Stat));
// enter the right hand side expression
rhsx = PopExpr();
WRITE_STAT(cs, stat, 2, rhsx);
// enter the name expression
rnam = PopExpr();
WRITE_STAT(cs, stat, 1, rnam);
// enter the record expression
rec = PopExpr();
WRITE_STAT(cs, stat, 0, rec);
// push the assignment
PushStat( stat );
}
void CodeUnbRecName(CodeState * cs, UInt rnam)
{
Stat stat; // unbind, result
Expr rec; // record expression
// allocate the unbind
stat = NewStat(cs, STAT_UNB_REC_NAME, 2 * sizeof(Stat));
// enter the name
WRITE_STAT(cs, stat, 1, rnam);
// enter the record expression
rec = PopExpr();
WRITE_STAT(cs, stat, 0, rec);
// push the unbind
PushStat( stat );
}
void CodeUnbRecExpr(CodeState * cs)
{
Stat stat; // unbind, result
Expr rec; // record expression
Expr rnam; // name expression
// allocate the unbind
stat = NewStat(cs, STAT_UNB_REC_EXPR, 2 * sizeof(Stat));
// enter the name expression
rnam = PopExpr();
WRITE_STAT(cs, stat, 1, rnam);
// enter the record expression
rec = PopExpr();
WRITE_STAT(cs, stat, 0, rec);
// enter the position expression
pos = PopExpr();
WRITE_EXPR(cs, ref, 1, pos);
// enter the posobj expression
posobj = PopExpr();
WRITE_EXPR(cs, ref, 0, posobj);
// push the isbound
PushExpr( ref );
}
/**************************************************************************** ** *FCodeAssComObjName(<rnam>).........codeassignmenttoacomobj *FCodeAssComObjExpr().............codeassignmenttoacomobj
*/
void CodeAssComObjName(CodeState * cs, UInt rnam)
{
Stat stat; // assignment, result
Expr comobj; // comobj expression
Expr rhsx; // right hand side expression
// allocate the assignment
stat = NewStat(cs, STAT_ASS_COMOBJ_NAME, 3 * sizeof(Stat));
// enter the right hand side expression
rhsx = PopExpr();
WRITE_STAT(cs, stat, 2, rhsx);
// enter the name
WRITE_STAT(cs, stat, 1, rnam);
// enter the comobj expression
comobj = PopExpr();
WRITE_STAT(cs, stat, 0, comobj);
// push the assignment
PushStat( stat );
}
void CodeAssComObjExpr(CodeState * cs)
{
Stat stat; // assignment, result
Expr comobj; // comobj expression
Expr rnam; // name expression
Expr rhsx; // right hand side expression
// allocate the assignment
stat = NewStat(cs, STAT_ASS_COMOBJ_EXPR, 3 * sizeof(Stat));
// enter the right hand side expression
rhsx = PopExpr();
WRITE_STAT(cs, stat, 2, rhsx);
// enter the name expression
rnam = PopExpr();
WRITE_STAT(cs, stat, 1, rnam);
// enter the comobj expression
comobj = PopExpr();
WRITE_STAT(cs, stat, 0, comobj);
// push the assignment
PushStat( stat );
}
void CodeUnbComObjName(CodeState * cs, UInt rnam)
{
Stat stat; // unbind, result
Expr comobj; // comobj expression
// allocate the unbind
stat = NewStat(cs, STAT_UNB_COMOBJ_NAME, 2 * sizeof(Stat));
// enter the name
WRITE_STAT(cs, stat, 1, rnam);
// enter the comobj expression
comobj = PopExpr();
WRITE_STAT(cs, stat, 0, comobj);
// push the unbind
PushStat( stat );
}
void CodeUnbComObjExpr(CodeState * cs)
{
Stat stat; // unbind, result
Expr comobj; // comobj expression
Expr rnam; // name expression
// allocate the unbind
stat = NewStat(cs, STAT_UNB_COMOBJ_EXPR, 2 * sizeof(Stat));
// enter the name expression
rnam = PopExpr();
WRITE_STAT(cs, stat, 1, rnam);
// enter the comobj expression
comobj = PopExpr();
WRITE_STAT(cs, stat, 0, comobj);
void CodeEmpty(CodeState * cs)
{
Stat stat;
stat = NewStat(cs, STAT_EMPTY, 0);
PushStat( stat );
}
/****************************************************************************
**
*F CodeInfoBegin() . . . . . . . . . . . . . start coding of Info statement
*F CodeInfoMiddle() . . . . . . . . . shift to coding printable arguments
*F CodeInfoEnd( <narg> ) . . Info statement complete, <narg> things to print
**
** These actions deal with the Info statement, which is coded specially,
** because notallof its arguments are always evaluated.
**
** Only CodeInfoEnd actually does anything
*/
void CodeInfoBegin(CodeState * cs)
{
}
void CodeInfoMiddle(CodeState * cs)
{
}
void CodeInfoEnd(CodeState * cs, UInt narg)
{
Stat stat; // we build the statement here
Expr expr; // expression
UInt i; // loop variable
// allocate the new statement
stat = NewStat(cs, STAT_INFO, SIZE_NARG_INFO(2 + narg));
// narg only counts the printable arguments
for ( i = narg + 2; 0 < i; i-- ) {
expr = PopExpr();
SET_ARGI_INFO(stat, i, expr);
}
// push the statement
PushStat( stat );
}
/****************************************************************************
**
*F CodeAssertBegin() . . . . . . . start interpretation of Assert statement
*F CodeAsseerAfterLevel() . . called after the first argument has been read
*F CodeAssertAfterCondition() called after the second argument has been read
*F CodeAssertEnd2Args() . . . . called after reading the closing parenthesis
*F CodeAssertEnd3Args() . . . . called after reading the closing parenthesis
**
** Only the End functions actually do anything
*/
void CodeAssertBegin(CodeState * cs)
{
}
void CodeAssertAfterLevel(CodeState * cs)
{
}
void CodeAssertAfterCondition(CodeState * cs)
{
}
void CodeAssertEnd2Args(CodeState * cs)
{
Stat stat; // we build the statement here
stat = NewStat(cs, STAT_ASSERT_2ARGS, 2 * sizeof(Expr));
/****************************************************************************
**
*F SaveBody( <body> ) . . . . . . . . . . . . . . . workspace saving method
**
** A body is made up of statements and expressions, and these are all
** organised to regular boundaries based on the types Stat and Expr, which
** are currently both UInt
**
** String literals should really be saved byte-wise, to be safe across
** machines of different endianness, but this would mean parsing the bag as
** we save it which it would be nice to avoid just now.
*/
#ifdef GAP_ENABLE_SAVELOAD
static void SaveBody(Obj body)
{
UInt i; const UInt *ptr = (const UInt *) CONST_ADDR_OBJ(body); // Save the new information in the body
for (i =0; i < sizeof(BodyHeader)/sizeof(Obj); i++)
SaveSubObj((Obj)(*ptr++)); // and the rest for(;i<(SIZE_OBJ(body)+sizeof(UInt)-1)/sizeof(UInt);i++) SaveUInt(*ptr++); } #endif
/**************************************************************************** ** *FLoadBody(<body>)...............workspaceloadingmethod ** **Abodyismadeupofstatementsandexpressions,andtheseareall **organisedtoregularboundariesbasedonthetypesStatandExpr,which **arecurrentlybothUInt ** */ #ifdefGAP_ENABLE_SAVELOAD staticvoidLoadBody(Objbody) { UInti; UInt*ptr;
ptr = (UInt *) ADDR_OBJ(body);
for (i =0; i < sizeof(BodyHeader)/sizeof(Obj); i++)
*(Obj *)(ptr++) = LoadSubObj();
for (; i < (SIZE_OBJ(body)+sizeof(UInt)-1)/sizeof(UInt); i++)
*ptr++ = LoadUInt();
}
#endif
/****************************************************************************
**
*F PreSave( <module> ) . . . . . . . clean up before saving
*/
static Int PreSave (
StructInitInfo * module )
{ // Can't save in mid-parsing if (CS(CountExpr) || CS(CountStat))
return 1;
// push the FP cache index out into a GAP Variable
AssGVar(GVarName("SavedFloatIndex"), INTOBJ_INT(NextFloatExprNumber));
// clean any old data out of the statement and expression stacks, // but leave the type field alone
memset(ADDR_OBJ(CS(StackStat)) + 1, 0, SIZE_BAG(CS(StackStat)) - sizeof(Obj));
memset(ADDR_OBJ(CS(StackExpr)) + 1, 0, SIZE_BAG(CS(StackExpr)) - sizeof(Obj));
return 0;
}
static Int InitModuleState(void)
{ // allocate the statements and expressions stacks
CS(StackStat) = NewKernelBuffer(sizeof(Obj) + 64 * sizeof(Stat));
CS(StackExpr) = NewKernelBuffer(sizeof(Obj) + 64 * sizeof(Expr));
return 0;
}
/****************************************************************************
**
*F InitInfoCode() . . . . . . . . . . . . . . . . . table of init functions
*/
static StructInitInfo module = { // init struct using C99 designated initializers; for a full list of // fields, please refer to the definition of StructInitInfo
.type = MODULE_BUILTIN,
.name = "code",
.initKernel = InitKernel,
.preSave = PreSave,
.postRestore = PostRestore,
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.135Bemerkung:
(vorverarbeitet am 2026-06-10)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.