diff --git a/.github/workflows/build-all-versions.yml b/.github/workflows/build-all-versions.yml
index df71f0ac0..46bd05b23 100644
--- a/.github/workflows/build-all-versions.yml
+++ b/.github/workflows/build-all-versions.yml
@@ -33,7 +33,7 @@ jobs:
- uses: actions/checkout@v2
if: github.event.action == 'opened' || github.event.action == 'synchronize' || github.event.ref == 'refs/heads/master'
- - uses: actions/setup-haskell@v1.1.1
+ - uses: actions/setup-haskell@v1.1.4
id: setup-haskell-cabal
name: Setup Haskell
with:
@@ -73,7 +73,7 @@ jobs:
- uses: actions/checkout@v2
if: github.event.action == 'opened' || github.event.action == 'synchronize' || github.event.ref == 'refs/heads/master'
- - uses: actions/setup-haskell@v1.1
+ - uses: actions/setup-haskell@v1.1.4
name: Setup Haskell Stack
with:
# ghc-version: ${{ matrix.ghc }}
diff --git a/Setup.hs b/Setup.hs
index 1ee9cec92..f8309cc00 100644
--- a/Setup.hs
+++ b/Setup.hs
@@ -28,17 +28,17 @@ main = defaultMainWithHooks simpleUserHooks
return emptyHookedBuildInfo
gfPostBuild args flags pkg lbi = do
- noRGLmsg
+ -- noRGLmsg
let gf = default_gf lbi
buildWeb gf flags (pkg,lbi)
gfPostInst args flags pkg lbi = do
- noRGLmsg
+ -- noRGLmsg
saveInstallPath args flags (pkg,lbi)
installWeb (pkg,lbi)
gfPostCopy args flags pkg lbi = do
- noRGLmsg
+ -- noRGLmsg
saveCopyPath args flags (pkg,lbi)
copyWeb flags (pkg,lbi)
diff --git a/doc/gf-refman.md b/doc/gf-refman.md
index 2a53041d9..503a5060c 100644
--- a/doc/gf-refman.md
+++ b/doc/gf-refman.md
@@ -1809,6 +1809,23 @@ As the last rule, subtyping is transitive:
- if *A* is a subtype of *B* and *B* is a subtype of *C*, then *A* is
a subtype of *C*.
+### List categories
+
+[]{#lists}
+
+Since categories of lists of elements of another category are a common idiom, the following syntactic sugar is available:
+
+ cat [C] {n}
+
+abbreviates a set of three judgements:
+
+ cat ListC ;
+ fun BaseC : C -> ... -> C -> ListC ; --n C’s
+ fun ConsC : C -> ListC -> ListC
+
+The functions `BaseC` and `ConsC` are automatically generated in the abstract syntax, but their linearizations, as well as the linearization type of `ListC`, must be defined manually. The type expression `[C]` is in all contexts interchangeable with `ListC`.
+
+More information on lists in GF can be found [here](https://inariksit.github.io/gf/2021/02/22/lists.html).
### Tables and table types
@@ -2113,7 +2130,7 @@ of *x*, and the application thereby disappears.
[]{#reuse}
-*This section is valid for GF 3.0, which abandons the \"lock field\"*
+*This section is valid for GF 3.0, which abandons the \"[lock field](https://inariksit.github.io/gf/2018/05/25/subtyping-gf.html#lock-fields)\"*
*discipline of GF 2.8.*
As explained [here](#openabstract), abstract syntax modules can be
diff --git a/index.html b/index.html
index e3df1ae22..857f6b153 100644
--- a/index.html
+++ b/index.html
@@ -88,7 +88,7 @@
Mailing List
Issue Tracker
Authors
- Summer School
+ Summer School
@@ -228,14 +228,14 @@ least one, it may help you to get a first idea of what GF is.
News
+ - 2021-03-01
+ -
+ Seventh GF Summer School, in Singapore and online, 26 July – 8 August 2021.
+
- 2020-09-29
-
Abstract Syntax as Interlingua: Scaling Up the Grammatical Framework from Controlled Languages to Robust Pipelines. A paper in Computational Linguistics (2020) summarizing much of the development in GF in the past ten years.
- - 2020-03-29
- -
- Seventh GF Summer School in Singapore has been postponed because of the corona pandemic.
-
- 2018-12-03
-
Sixth GF Summer School in Stellenbosch (South Africa), 3–14 December 2018
diff --git a/src/compiler/GF/Compile/GeneratePMCFG.hs b/src/compiler/GF/Compile/GeneratePMCFG.hs
index 35c25cc0d..ab6476b31 100644
--- a/src/compiler/GF/Compile/GeneratePMCFG.hs
+++ b/src/compiler/GF/Compile/GeneratePMCFG.hs
@@ -622,7 +622,9 @@ ppbug msg = error completeMsg
where
originalMsg = render $ hang "Internal error in GeneratePMCFG:" 4 msg
completeMsg =
- unlines [originalMsg
+ case render msg of -- the error message for pattern matching a runtime string
+ "descend (CStr 0,CNil,CProj (LIdent (Id {rawId2utf8 = \"s\"})) CNil)"
+ -> unlines [originalMsg -- add more helpful output
,""
,"1) Check that you are not trying to pattern match a /runtime string/."
," These are illegal:"
@@ -633,5 +635,6 @@ ppbug msg = error completeMsg
,"2) Not about pattern matching? Submit a bug report and we update the error message."
," https://github.com/GrammaticalFramework/gf-core/issues"
]
+ _ -> originalMsg -- any other message: just print it as is
ppU = ppTerm Unqualified
diff --git a/src/runtime/c/gu/map.c b/src/runtime/c/gu/map.c
index dc19bc932..ebd917b3e 100644
--- a/src/runtime/c/gu/map.c
+++ b/src/runtime/c/gu/map.c
@@ -322,7 +322,7 @@ gu_map_iter(GuMap* map, GuMapItor* itor, GuExn* err)
}
GU_API bool
-gu_map_next(GuMap* map, size_t* pi, void** pkey, void* pvalue)
+gu_map_next(GuMap* map, size_t* pi, void* pkey, void* pvalue)
{
while (*pi < map->data.n_entries) {
if (gu_map_entry_is_free(map, &map->data, *pi)) {
@@ -330,14 +330,17 @@ gu_map_next(GuMap* map, size_t* pi, void** pkey, void* pvalue)
continue;
}
- *pkey = &map->data.keys[*pi * map->key_size];
if (map->hasher == gu_addr_hasher) {
- *pkey = *(void**) *pkey;
+ *((void**) pkey) = *((void**) &map->data.keys[*pi * sizeof(void*)]);
+ } else if (map->hasher == gu_word_hasher) {
+ *((GuWord*) pkey) = *((GuWord*) &map->data.keys[*pi * sizeof(GuWord)]);
} else if (map->hasher == gu_string_hasher) {
- *pkey = *(void**) *pkey;
- }
+ *((GuString*) pkey) = *((GuString*) &map->data.keys[*pi * sizeof(GuString)]);
+ } else {
+ memcpy(pkey, &map->data.keys[*pi * map->key_size], map->key_size);
+ }
- memcpy(pvalue, &map->data.values[*pi * map->cell_size],
+ memcpy(pvalue, &map->data.values[*pi * map->cell_size],
map->value_size);
(*pi)++;
diff --git a/src/runtime/c/gu/map.h b/src/runtime/c/gu/map.h
index cc91a27f7..7ac33dc3b 100644
--- a/src/runtime/c/gu/map.h
+++ b/src/runtime/c/gu/map.h
@@ -75,7 +75,7 @@ GU_API_DECL void
gu_map_iter(GuMap* ht, GuMapItor* itor, GuExn* err);
GU_API bool
-gu_map_next(GuMap* map, size_t* pi, void** pkey, void* pvalue);
+gu_map_next(GuMap* map, size_t* pi, void* pkey, void* pvalue);
typedef GuMap GuIntMap;
diff --git a/src/runtime/c/pgf/graphviz.c b/src/runtime/c/pgf/graphviz.c
index a404ed009..f46b8dd3a 100644
--- a/src/runtime/c/pgf/graphviz.c
+++ b/src/runtime/c/pgf/graphviz.c
@@ -192,7 +192,7 @@ pgf_bracket_lzn_begin_phrase(PgfLinFuncs** funcs, PgfCId cat, int fid, GuString
}
static void
-pgf_bracket_lzn_end_phrase(PgfLinFuncs** funcs, PgfCId cat, int fid, size_t lindex, PgfCId fun)
+pgf_bracket_lzn_end_phrase(PgfLinFuncs** funcs, PgfCId cat, int fid, GuString ann, PgfCId fun)
{
PgfBracketLznState* state = gu_container(funcs, PgfBracketLznState, funcs);
diff --git a/src/runtime/python/pypgf.c b/src/runtime/python/pypgf.c
index e009d9e72..eebaa2781 100644
--- a/src/runtime/python/pypgf.c
+++ b/src/runtime/python/pypgf.c
@@ -2077,6 +2077,58 @@ static PyTypeObject pgf_BracketType = {
0, /*tp_new */
};
+typedef struct {
+ PyObject_HEAD
+} BINDObject;
+
+static PyObject *
+BIND_repr(BINDObject *self)
+{
+ return PyString_FromString("&+");
+}
+
+static PyTypeObject pgf_BINDType = {
+ PyVarObject_HEAD_INIT(NULL, 0)
+ //0, /*ob_size*/
+ "pgf.BIND", /*tp_name*/
+ sizeof(BINDObject), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ 0, /*tp_dealloc*/
+ 0, /*tp_print*/
+ 0, /*tp_getattr*/
+ 0, /*tp_setattr*/
+ 0, /*tp_compare*/
+ 0, /*tp_repr*/
+ 0, /*tp_as_number*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash */
+ 0, /*tp_call*/
+ (reprfunc) BIND_repr, /*tp_str*/
+ 0, /*tp_getattro*/
+ 0, /*tp_setattro*/
+ 0, /*tp_as_buffer*/
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
+ "a marker for BIND in a bracketed string", /*tp_doc*/
+ 0, /*tp_traverse */
+ 0, /*tp_clear */
+ 0, /*tp_richcompare */
+ 0, /*tp_weaklistoffset */
+ 0, /*tp_iter */
+ 0, /*tp_iternext */
+ 0, /*tp_methods */
+ 0, /*tp_members */
+ 0, /*tp_getset */
+ 0, /*tp_base */
+ 0, /*tp_dict */
+ 0, /*tp_descr_get */
+ 0, /*tp_descr_set */
+ 0, /*tp_dictoffset */
+ 0, /*tp_init */
+ 0, /*tp_alloc */
+ 0, /*tp_new */
+};
+
typedef struct {
PgfLinFuncs* funcs;
GuBuf* stack;
@@ -2128,6 +2180,16 @@ pgf_bracket_lzn_end_phrase(PgfLinFuncs** funcs, PgfCId cat, int fid, GuString an
state->list = parent;
}
+static void
+pgf_bracket_lzn_symbol_bind(PgfLinFuncs** funcs)
+{
+ PgfBracketLznState* state = gu_container(funcs, PgfBracketLznState, funcs);
+
+ PyObject* bind = pgf_BINDType.tp_alloc(&pgf_BINDType, 0);
+ PyList_Append(state->list, bind);
+ Py_DECREF(bind);
+}
+
static void
pgf_bracket_lzn_symbol_meta(PgfLinFuncs** funcs, PgfMetaId meta_id)
{
@@ -2139,7 +2201,7 @@ static PgfLinFuncs pgf_bracket_lin_funcs = {
.begin_phrase = pgf_bracket_lzn_begin_phrase,
.end_phrase = pgf_bracket_lzn_end_phrase,
.symbol_ne = NULL,
- .symbol_bind = NULL,
+ .symbol_bind = pgf_bracket_lzn_symbol_bind,
.symbol_capit = NULL,
.symbol_meta = pgf_bracket_lzn_symbol_meta
};
@@ -3559,6 +3621,9 @@ MOD_INIT(pgf)
if (PyType_Ready(&pgf_BracketType) < 0)
return MOD_ERROR_VAL;
+ if (PyType_Ready(&pgf_BINDType) < 0)
+ return MOD_ERROR_VAL;
+
if (PyType_Ready(&pgf_ExprType) < 0)
return MOD_ERROR_VAL;
@@ -3605,5 +3670,8 @@ MOD_INIT(pgf)
PyModule_AddObject(m, "Bracket", (PyObject *) &pgf_BracketType);
Py_INCREF(&pgf_BracketType);
+ PyModule_AddObject(m, "BIND", (PyObject *) &pgf_BINDType);
+ Py_INCREF(&pgf_BINDType);
+
return MOD_SUCCESS_VAL(m);
}