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 );
}
// if it is small enough code it immediately if ( IS_INTOBJ(val) ) {
expr = INTEXPR_INT( INT_INTOBJ(val) );
}
// otherwise stuff the value into the values list else {
GAP_ASSERT(TNUM_OBJ(val) == T_INTPOS || TNUM_OBJ(val) == T_INTNEG);
expr = NewExpr(cs, EXPR_INTPOS, sizeof(UInt)); Int ix = AddValueToBody(cs, val);
WRITE_EXPR(cs, expr, 0, ix);
}
void CodeListExprBeginElm(CodeState * cs, UInt pos)
{ // push the literal integer value
PushExpr( INTEXPR_INT(pos) );
}
void CodeListExprEndElm(CodeState * cs)
{
}
void CodeListExprEnd(
CodeState * cs, UInt nr, UInt range, UInt top, UInt tilde)
{
Expr list; // list, result
Expr entry; // entry
Expr pos; // position of an entry
UInt i; // loop variable
// peek at the last position (which is the largest) if ( nr != 0 ) {
entry = PopExpr();
pos = PopExpr();
PushExpr( pos );
PushExpr( entry );
} else {
pos = INTEXPR_INT(0);
}
// allocate the list expression if ( ! range && ! (top && tilde) ) {
list = NewExpr(cs, EXPR_LIST, INT_INTEXPR(pos) * sizeof(Expr));
} elseif ( ! range && (top && tilde) ) {
list = NewExpr(cs, EXPR_LIST_TILDE, INT_INTEXPR(pos) * sizeof(Expr));
} else/* if ( range && ! (top && tilde) ) */ {
list = NewExpr(cs, EXPR_RANGE, INT_INTEXPR(pos) * sizeof(Expr));
}
// enter the entries for ( i = nr; 1 <= i; i-- ) {
entry = PopExpr();
pos = PopExpr();
WRITE_EXPR(cs, list, INT_INTEXPR(pos) - 1, entry);
}
// the maximal index must be less than INT_INTOBJ_MAX and INT_MAX, so // simply hardcode it to 1<<28
MAX_FLOAT_INDEX = (1<<28) - 2,
}; static UInt NextFloatExprNumber = 3;
static UInt CheckForCommonFloat(constChar * str)
{ // skip leading zeros while (*str == '0')
str++; // might be zero literal if (*str == '.') { // skip point
str++; // skip more zeroes while (*str == '0')
str++; // if we've got to end of string we've got zero. if (!IsDigit(*str)) return FLOAT_0_INDEX;
} if (*str++ != '1') return0; // might be one literal if (*str++ != '.') return0; // skip zeros while (*str == '0')
str++; if (*str == '\0') return FLOAT_1_INDEX; if (IsDigit(*str)) return0; // must now be an exponent character
assert(IsAlpha(*str)); // skip it
str++; /*skip + and - in exponent */ if (*str == '+' || *str == '-')
str++; // skip leading zeros in the exponent while (*str == '0')
str++; // if there's anything but leading zeros this isn't a one literal if (*str == '\0') return FLOAT_1_INDEX; else return0;
}
// allocate the isbound
ref = NewExpr(cs, EXPR_ISB_GVAR, sizeof(Expr));
// enter the global variable
WRITE_EXPR(cs, ref, 0, gvar);
// push the isbound
PushExpr( ref );
}
/**************************************************************************** ** *FCodeAssList().................codeassignmenttoalist *FCodeAsssList()...........codemultipleassignmenttoalist *FCodeAssListLevel(<level>)......codeassignmenttoseverallists *FCodeAsssListLevel(<level>).codemultipleassignmenttoseverallists
*/ staticvoid CodeAssListUniv(CodeState * cs, Stat ass, Int narg)
{
Expr list; // list expression
Expr pos; // position expression
Expr rhsx; // right hand side expression Int i;
// enter the right hand side expression
rhsx = PopExpr();
WRITE_STAT(cs, ass, narg + 1, rhsx);
// enter the position expression 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 assignment
PushStat( ass );
}
void CodeAssList(CodeState * cs, Int narg)
{
Stat ass; // assignment, result
GAP_ASSERT(narg == 1 || narg == 2);
// allocate the assignment if (narg == 1)
ass = NewStat(cs, STAT_ASS_LIST, 3 * sizeof(Stat)); else// if (narg == 2)
ass = NewStat(cs, STAT_ASS_MAT, 4 * sizeof(Stat));
// let 'CodeAssListUniv' do the rest
CodeAssListUniv(cs, ass, narg);
}
void CodeAsssList(CodeState * cs)
{
Stat ass; // assignment, result
// allocate the assignment
ass = NewStat(cs, STAT_ASSS_LIST, 3 * sizeof(Stat));
// let 'CodeAssListUniv' do the rest
CodeAssListUniv(cs, ass, 1);
}
void CodeAssListLevel(CodeState * cs, Int narg, UInt level)
{
Stat ass; // assignment, result
// allocate the assignment and enter the level
ass = NewStat(cs, STAT_ASS_LIST_LEV, (narg + 3) * sizeof(Stat));
WRITE_STAT(cs, ass, narg + 2, level);
// let 'CodeAssListUniv' do the rest
CodeAssListUniv(cs, ass, narg);
}
void CodeAsssListLevel(CodeState * cs, UInt level)
{
Stat ass; // assignment, result
// allocate the assignment and enter the level
ass = NewStat(cs, STAT_ASSS_LIST_LEV, 4 * sizeof(Stat));
WRITE_STAT(cs, ass, 3, level);
// let 'CodeAssListUniv' do the rest
CodeAssListUniv(cs, ass, 1);
}
/**************************************************************************** ** *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
*/ staticvoid 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);
/**************************************************************************** ** *FSaveBody(<body>)...............workspacesavingmethod ** **Abodyismadeupofstatementsandexpressions,andtheseareall **organisedtoregularboundariesbasedonthetypesStatandExpr,which **arecurrentlybothUInt ** **Stringliteralsshouldreallybesavedbyte-wise,tobesafeacross **machinesofdifferentendianness,butthiswouldmeanparsingthebagas **wesaveitwhichitwouldbenicetoavoidjustnow.
*/ #ifdef GAP_ENABLE_SAVELOAD staticvoid 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 **
*/ #ifdef GAP_ENABLE_SAVELOAD staticvoid LoadBody(Obj body)
{
UInt i;
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
/**************************************************************************** ** *FPreSave(<module>).......cleanupbeforesaving
*/ staticInt PreSave (
StructInitInfo * module )
{ // Can't save in mid-parsing if (CS(CountExpr) || CS(CountStat)) return1;
// 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));
/**************************************************************************** ** *FInitInfoCode().................tableofinitfunctions
*/ 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.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.