// evaluate the expression
val = EVAL_EXPR( expr );
// check that the value is either 'true' or 'false' if (val != True && val != False) {
RequireArgumentEx(0, val, "<expr>", "must be 'true' or 'false'");
}
static Obj EvalPermExpr(Expr expr)
{
Obj perm; // permutation, result
UInt m; // maximal entry in permutation
Expr cycle; // one cycle of permutation
UInt i; // loop variable
// special case for identity permutation if ( SIZE_EXPR(expr) == 0 ) { return IdentityPerm;
}
// allocate the new permutation
m = 0;
perm = NEW_PERM4( 0 );
// loop over the cycles for ( i = 1; i <= SIZE_EXPR(expr)/sizeof(Expr); i++ ) {
cycle = READ_EXPR(expr, i - 1);
// Need to inform profiling this cycle expression is executed, as // we never call EVAL_EXPR on it.
VisitStatIfHooked(cycle);
m = ScanPermCycle(perm, m, (Obj)cycle,
SIZE_EXPR(cycle) / sizeof(Expr), GetFromExpr);
}
// if possible represent the permutation with short entries
TrimPerm(perm, m);
// return the permutation return perm;
}
/**************************************************************************** ** *FEvalListExpr(<expr>).....evaluatelistexpressiontoalistvalue ** **'EvalListExpr'evaluatesthelistexpression,i.e.,notyetevaluated **list,<expr>toalistvalue.
*/ static Obj EvalListExpr(Expr expr)
{
Obj list; // list value, result
Obj sub; // value of a subexpression Int len; // logical length of the list Int i; // loop variable Int dense; // track whether list is dense
// get the length of the list
len = SIZE_EXPR(expr) / sizeof(Expr);
// handle empty list if (len == 0) { return NewEmptyPlist();
}
// allocate the list value
list = NEW_PLIST(T_PLIST, len);
// set the final list length
SET_LEN_PLIST(list, len);
// initially assume list is dense
dense = 1;
// handle the subexpressions for (i = 1; i <= len; i++) {
Expr subExpr = READ_EXPR(expr, i - 1);
// skip holes if (subExpr == 0) { // there is a hole, hence the list is not dense (note that list // expressions never contain holes at the end, so we do not have // to check if any bound entries follow)
dense = 0; continue;
}
sub = EVAL_EXPR(subExpr);
SET_ELM_PLIST(list, i, sub);
CHANGED_BAG(list);
}
/**************************************************************************** ** *FEvalListTildeExpr(<expr>)....evaluatealistexpressionwithatilde ** **'EvalListTildeExpr'evaluatesthelistexpression,i.e.,notyet **evaluatedlist,<expr>toalistvalue.Thedifferenceto'EvalListExpr' **isthatin<expr>thereareoccurrencesof'~'referringtothislist **value. ** **Notethatwedonottrackherewhetherthelistisdense,asthiscanbe **changedbycodeinvolvingatildeexpression,asinthisexample: **x:=[1,,3,function(x)x[2]:=2;return4;end(~)]; ** **Forsimilarreasons,wemustdealwiththepossibilitythatthelistwe **arecreatingchangesitsrepresentation,andthusmustuseASS_LIST **insteadofSET_ELM_PLIST.
*/ static Obj EvalListTildeExpr(Expr expr)
{
Obj list; // list value, result
Obj tilde; // old value of tilde
Obj sub; // value of a subexpression Int len; // logical length of the list Int i; // loop variable
// get the length of the list
len = SIZE_EXPR(expr) / sizeof(Expr);
// list expressions with tilde cannot be empty
GAP_ASSERT(len > 0);
// allocate the list value
list = NEW_PLIST(T_PLIST, len);
// remember the old value of '~'
tilde = STATE(Tilde);
// assign the list to '~'
STATE(Tilde) = list;
// handle the subexpressions for (i = 1; i <= len; i++) {
Expr subExpr = READ_EXPR(expr, i - 1);
// skip holes if (subExpr == 0) continue;
sub = EVAL_EXPR(subExpr);
ASS_LIST(list, i, sub);
}
// restore old value of '~'
STATE(Tilde) = tilde;
return list;
}
/**************************************************************************** ** *FEvalRangeExpr(<expr>).....evalarangeexpressiontoarangevalue ** **'EvalRangeExpr'evaluatestherangeexpression<expr>toarangevalue.
*/ static Obj EvalRangeExpr(Expr expr)
{
Obj range; // range, result
Obj val; // subvalue of range Int low; // low (as C integer) Int inc; // increment (as C integer) Int high; // high (as C integer)
// evaluate the low value
val = EVAL_EXPR(READ_EXPR(expr, 0));
low = GetSmallIntEx("Range", val, "<first>");
// evaluate the second value (if present) if ( SIZE_EXPR(expr) == 3*sizeof(Expr) ) {
val = EVAL_EXPR(READ_EXPR(expr, 1)); Int ival = GetSmallIntEx("Range", val, "<second>"); if (ival == low) {
ErrorMayQuit("Range: <second> must not be equal to <first> (%d)",
(Int)low, 0);
}
inc = ival - low;
} else {
inc = 1;
}
// evaluate and check the high value
val = EVAL_EXPR(READ_EXPR(expr, SIZE_EXPR(expr) / sizeof(Expr) - 1));
high = GetSmallIntEx("Range", val, "<last>"); if ((high - low) % inc != 0) {
ErrorMayQuit( "Range: <last>-<first> (%d) must be divisible by <inc> (%d)",
(Int)(high - low), (Int)inc);
}
// if <low> is larger than <high> the range is empty if ( (0 < inc && high < low) || (inc < 0 && low < high) ) {
range = NewEmptyPlist();
}
// if <low> is equal to <high> the range is a singleton list elseif ( low == high ) {
range = NEW_PLIST( T_PLIST_CYC_SSORT, 1 );
SET_LEN_PLIST( range, 1 );
SET_ELM_PLIST( range, 1, INTOBJ_INT(low) );
}
// else make the range else { // the length must be a small integer as well if ((high-low) / inc + 1 > INT_INTOBJ_MAX) {
ErrorQuit("Range: the length of a range must be a small integer", 0, 0);
}
range = NEW_RANGE((high - low) / inc + 1, low, inc);
}
static Obj EvalRecExpr(Expr expr)
{
Obj rec; // record value, result
// evaluate the record expression
rec = RecExpr1( expr );
RecExpr2( rec, expr );
return rec;
}
/**************************************************************************** ** *FEvalRecTildeExpr(<expr>)...evaluatearecordexpressionwithatilde ** **'EvalRecTildeExpr'evaluatestherecordexpression,i.e.,notyet **evaluatedrecord,<expr>toarecordvalue.Thedifferenceto **'EvalRecExpr'isthatin<expr>thereareoccurrencesof'~'referringto **thisrecordvalue. ** **'EvalRecTildeExpr'justcalls'RecExpr1'tocreatetherecord,assigns **therecordtothevariable'~',andfinallycalls'RecExpr2'toevaluate **thesubexpressionsintotherecord.Thussubexpressionsintherecord **expressioncanrefertothisvariableanditssubobjectstocreate **objectsthatarenottrees.
*/ static Obj EvalRecTildeExpr(Expr expr)
{
Obj rec; // record value, result
Obj tilde; // old value of tilde
// remember the old value of '~'
tilde = STATE(Tilde);
// create the record value
rec = RecExpr1( expr );
// assign the record value to the variable '~'
STATE(Tilde) = rec;
// evaluate the subexpressions into the record value
RecExpr2( rec, expr );
// restore the old value of '~'
STATE(Tilde) = tilde;
// return the record value return rec;
}
/**************************************************************************** ** *FRecExpr1(<expr>).........makearecordforarecordexpression *FRecExpr2(<rec>,<expr>)..enterthesubobjectsforarecordexpression ** **'RecExpr1'and'RecExpr2'togetherevaluatetherecordexpression<expr> **intotherecord<rec>. ** **'RecExpr1'allocatesanewrecordofthesamesizeastherecord **expression<expr>andreturnsthisrecord. ** **'RecExpr2'evaluatesthesubexpressionsof<expr>andputsthevalues **intotherecord<rec>(whichshouldbearecordofthesamesizeasthe **recordexpression<expr>,e.g.,theoneallocatedby'RecExpr1'). ** **Thistwostepallocationisnecessary,becauserecordexpressionssuchas **'rec(a:=1,~.a)'requiresthatthevalueofonesubexpressionis **enteredintotherecordvaluebeforethenextsubexpressionisevaluated.
*/ static Obj RecExpr1(Expr expr)
{
Obj rec; // record value, result Int len; // number of components
// get the number of components
len = SIZE_EXPR( expr ) / (2*sizeof(Expr));
// allocate the record value
rec = NEW_PREC( len );
// return the record return rec;
}
staticvoid RecExpr2(Obj rec, Expr expr)
{
UInt rnam; // name of component
Obj sub; // value of subexpression Int len; // number of components
Expr tmp; // temporary variable Int i; // loop variable
// get the number of components
len = SIZE_EXPR( expr ) / (2*sizeof(Expr));
// handle the subexpressions for ( i = 1; i <= len; i++ ) {
// handle the name
tmp = READ_EXPR(expr, 2 * i - 2); if ( IS_INTEXPR(tmp) ) {
rnam = (UInt)INT_INTEXPR(tmp);
} else {
rnam = RNamObj( EVAL_EXPR(tmp) );
}
// if the subexpression is empty (cannot happen for records)
tmp = READ_EXPR(expr, 2 * i - 1); if ( tmp == 0 ) { continue;
}
sub = EVAL_EXPR( tmp );
AssPRec(rec,rnam,sub);
}
SortPRecRNam(rec);
}
// select the new precedence level switch ( TNUM_EXPR(expr) ) { case EXPR_OR: op = "or"; PrintPrecedence = 2; break; case EXPR_AND: op = "and"; PrintPrecedence = 4; break; case EXPR_EQ: op = "="; PrintPrecedence = 8; break; case EXPR_LT: op = "<"; PrintPrecedence = 8; break; case EXPR_GT: op = ">"; PrintPrecedence = 8; break; case EXPR_NE: op = "<>"; PrintPrecedence = 8; break; case EXPR_LE: op = "<="; PrintPrecedence = 8; break; case EXPR_GE: op = ">="; PrintPrecedence = 8; break; case EXPR_IN: op = "in"; PrintPrecedence = 8; break; case EXPR_SUM: op = "+"; PrintPrecedence = 10; break; case EXPR_DIFF: op = "-"; PrintPrecedence = 10; break; case EXPR_PROD: op = "*"; PrintPrecedence = 12; break; case EXPR_QUO: op = "/"; PrintPrecedence = 12; break; case EXPR_MOD: op = "mod"; PrintPrecedence = 12; break; case EXPR_POW: op = "^"; PrintPrecedence = 16; break; default: op = "<bogus-operator>"; break;
} // The logical operators (=|<>|<|>|<=|>=|in) need brackets at // equal precedence level if (PrintPrecedence == 8) {
printEqPrec = TRUE;
}
// if necessary print the opening parenthesis if (oldPrec > PrintPrecedence ||
(oldPrec == PrintPrecedence && printEqPrec))
Pr("%>(%>", 0, 0); else Pr("%2>", 0, 0);
/**************************************************************************** ** *FPrintPermExpr(<expr>)..........printapermutationexpression ** **'PrintPermExpr'printsthepermutationexpression<expr>.
*/ staticvoid PrintPermExpr(Expr expr)
{
Expr cycle; // one cycle of permutation expr.
UInt i, j; // loop variables
// if there are no cycles, print the identity permutation if ( SIZE_EXPR(expr) == 0 ) {
Pr("()", 0, 0);
}
// print all cycles for ( i = 1; i <= SIZE_EXPR(expr)/sizeof(Expr); i++ ) {
cycle = READ_EXPR(expr, i - 1);
Pr("%>(", 0, 0);
// print all entries of that cycle for ( j = 1; j <= SIZE_EXPR(cycle)/sizeof(Expr); j++ ) {
Pr("%>", 0, 0);
PrintExpr(READ_EXPR(cycle, j - 1));
Pr("%<", 0, 0); if ( j < SIZE_EXPR(cycle)/sizeof(Expr) ) Pr(",", 0, 0);
}
Pr("%<)", 0, 0);
}
}
/**************************************************************************** ** *FPrintListExpr(<expr>)..............printalistexpression ** **'PrintListExpr'printsthelistexpression<expr>.
*/ staticvoid PrintListExpr(Expr expr)
{ Int len; // logical length of <list>
Expr elm; // one element from <list> Int i; // loop variable
// get the logical length of the list
len = SIZE_EXPR( expr ) / sizeof(Expr);
// loop over the entries
Pr("%2>[ %2>", 0, 0); for ( i = 1; i <= len; i++ ) {
elm = READ_EXPR(expr, i - 1); if ( elm != 0 ) { if ( 1 < i ) Pr("%<,%< %2>", 0, 0);
PrintExpr( elm );
} else { if ( 1 < i ) Pr("%2<,%2>", 0, 0);
}
}
Pr(" %4<]", 0, 0);
}
for ( i = 1; i <= SIZE_EXPR(expr)/(2*sizeof(Expr)); i++ ) { // print an ordinary record name
tmp = READ_EXPR(expr, 2 * i - 2); if ( IS_INTEXPR(tmp) ) {
Pr("%I", (Int)NAME_RNAM(INT_INTEXPR(tmp)), 0);
}
// print an evaluating record name else {
Pr(" (", 0, 0);
PrintExpr( tmp );
Pr(")", 0, 0);
}
// print the component
tmp = READ_EXPR(expr, 2 * i - 1);
Pr("%< := %>", 0, 0);
PrintExpr( tmp ); if ( i < SIZE_EXPR(expr)/(2*sizeof(Expr)) )
Pr("%2<,\n%2>", 0, 0);
}
}
// clear the evaluation dispatch table for ( type = 0; type < 256; type++ ) {
InstallEvalExprFunc( type , EvalUnknownExpr);
InstallEvalBoolFunc( type , EvalUnknownBool);
}
// install the evaluators for logical operations
InstallEvalExprFunc( EXPR_OR , EvalOr);
InstallEvalExprFunc( EXPR_AND , EvalAnd);
InstallEvalExprFunc( EXPR_NOT , EvalNot);
// the logical operations are guaranteed to return booleans
InstallEvalBoolFunc( EXPR_OR , EvalOr);
InstallEvalBoolFunc( EXPR_AND , EvalAnd);
InstallEvalBoolFunc( EXPR_NOT , EvalNot);
/**************************************************************************** ** *FInitInfoExprs().................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 = "exprs",
.initKernel = InitKernel,
.initLibrary = InitLibrary,
¤ 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.67Bemerkung:
(vorverarbeitet am 2026-09-27)
¤
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.