From d75a40224a22ab2c6e6b0783eab7e74e2a808b28 Mon Sep 17 00:00:00 2001 From: Max Horn Date: Fri, 16 Oct 2020 09:58:21 +0200 Subject: [PATCH] Extend BindConstant, MakeConstantGlobal to all object types Currently we only support these on integer and boolean values. This patch extends this to all object types. This would then simply be a "non-reversible" version of `MakeReadOnlyGlobal`; i.e., unlike that, a "constant global variables" can never be turned into a non-constant one. That is, it will always refer to the same object. Semantically this interpretation of `constness` is in line with other languages, such as Julia, where `const` refers to the (re)assignability of a variable identifier, *not* to the mutability of the object it refers to. (Note that this is admittedly somewhat confusing in GAP, with `MakeReadOnlyGlobal`/`MakeReadOnlyGVar` doing one thing and `MakeReadOnlyObj` doing something orthogonal (and for now only in HPC-GAP.... Note that no further use is made of this for now; in particular, unlike for small integer values, `true` and `false`, no attempt is made to "inline" constant object in function definitions. However, interfaces to other languages (such as the GAP-Julia interface) could exploit constness for various optimizations. --- lib/global.gd | 4 +--- src/gvars.c | 6 ------ src/read.c | 15 +++++++++------ tst/testinstall/constant.tst | 5 ++--- 4 files changed, 12 insertions(+), 18 deletions(-) diff --git a/lib/global.gd b/lib/global.gd index bdd99af192..e256dbb7f8 100644 --- a/lib/global.gd +++ b/lib/global.gd @@ -197,9 +197,7 @@ DeclareGlobalFunction("MakeReadWriteGlobal"); ## ## MakeConstantGlobal ( name ) marks the global variable named ## by the string name as constant. A constant variable can never -## be changed or made read-write. Constant variables can only take an -## integer value, true or false. There is a limit on -## the size of allowed integers. +## be reassigned or made read-write again. ##

## A warning is given if name is already constant. ## diff --git a/src/gvars.c b/src/gvars.c index 1053e73e61..f50c177de9 100644 --- a/src/gvars.c +++ b/src/gvars.c @@ -797,12 +797,6 @@ void MakeReadOnlyGVar ( */ void MakeConstantGVar(UInt gvar) { - Obj val = ValGVar(gvar); - if (!IS_INTOBJ(val) && val != True && val != False) { - ErrorMayQuit( - "Variable: '%g' must be assigned a small integer, true or false", - (Int)NameGVar(gvar), 0); - } SetGVarWriteState(gvar, GVarConstant); } diff --git a/src/read.c b/src/read.c index 7327ba7f7f..0c025a46e9 100644 --- a/src/read.c +++ b/src/read.c @@ -856,16 +856,19 @@ static void ReadCallVarAss(ReaderState * rs, TypSymbolSet follow, Char mode) if (mode == 'r' || (mode == 'x' && rs->s.Symbol != S_ASSIGN)) { Obj val = ValAutoGVar(ref.var); TRY_IF_NO_ERROR { - if (val == True) + if (val == True) { IntrTrueExpr(&rs->intr); - else if (val == False) + return; + } + else if (val == False) { IntrFalseExpr(&rs->intr); - else if (IS_INTOBJ(val)) + return; + } + else if (IS_INTOBJ(val)) { IntrIntObjExpr(&rs->intr, val); - else - SyntaxError(&rs->s, "Invalid constant variable"); + return; + } } - return; } } diff --git a/tst/testinstall/constant.tst b/tst/testinstall/constant.tst index 61f7a70aea..7cf9c401a2 100644 --- a/tst/testinstall/constant.tst +++ b/tst/testinstall/constant.tst @@ -44,12 +44,11 @@ true gap> Unbind(testvar); Error, Variable: 'testvar' is constant -# Try making a global var constants whose value is not eligible +# make a global var constants whose value is not a small integer, true or false gap> newtestvar := fail;; gap> MakeConstantGlobal("newtestvar"); -Error, Variable: 'newtestvar' must be assigned a small integer, true or false gap> IsConstantGlobal("newtestvar"); -false +true # some more tests with constant gvars with boolean value gap> booltruevar := true;;