From 36355f3d0c23357fccf2c76b3e9605a41cae519d Mon Sep 17 00:00:00 2001 From: Hans Hagen Date: Wed, 21 Dec 2022 18:00:37 +0100 Subject: 2022-12-21 17:12:00 --- source/luametatex/source/lua/lmtinterface.c | 2 + source/luametatex/source/lua/lmtinterface.h | 1 + source/luametatex/source/lua/lmtnodelib.c | 1 - source/luametatex/source/lua/lmttexlib.c | 153 +++++++++------ source/luametatex/source/lua/lmttokenlib.c | 6 +- source/luametatex/source/luametatex.h | 2 +- source/luametatex/source/tex/texcommands.c | 11 +- source/luametatex/source/tex/texcommands.h | 9 +- source/luametatex/source/tex/texdumpdata.h | 2 +- source/luametatex/source/tex/texequivalents.c | 34 ++++ source/luametatex/source/tex/texequivalents.h | 8 +- source/luametatex/source/tex/texmaincontrol.c | 256 +++++++++++++++++++------- source/luametatex/source/tex/texmath.c | 3 +- source/luametatex/source/tex/texnodes.c | 2 + source/luametatex/source/tex/texnodes.h | 7 +- source/luametatex/source/tex/texpackaging.c | 104 ++++++----- source/luametatex/source/tex/texpackaging.h | 2 + source/luametatex/source/tex/texscanning.c | 37 +++- source/luametatex/source/tex/textoken.c | 2 + source/luametatex/source/tex/textypes.h | 25 ++- 20 files changed, 480 insertions(+), 187 deletions(-) (limited to 'source/luametatex') diff --git a/source/luametatex/source/lua/lmtinterface.c b/source/luametatex/source/lua/lmtinterface.c index bc546a9e2..641c22f8f 100644 --- a/source/luametatex/source/lua/lmtinterface.c +++ b/source/luametatex/source/lua/lmtinterface.c @@ -88,6 +88,7 @@ void lmt_initialize_interface(void) set_group_code_value(adjusted_hbox_group, adjustedhbox); set_group_code_value(vbox_group, vbox); set_group_code_value(vtop_group, vtop); + set_group_code_value(dbox_group, dbox); set_group_code_value(align_group, align); set_group_code_value(no_align_group, noalign); set_group_code_value(output_group, output); @@ -123,6 +124,7 @@ void lmt_initialize_interface(void) set_par_context_value(vmode_par_context, vmode); set_par_context_value(vbox_par_context, vbox); set_par_context_value(vtop_par_context, vtop); + set_par_context_value(dbox_par_context, dbox); set_par_context_value(vcenter_par_context, vcenter); set_par_context_value(vadjust_par_context, vadjust); set_par_context_value(insert_par_context, insert); diff --git a/source/luametatex/source/lua/lmtinterface.h b/source/luametatex/source/lua/lmtinterface.h index c60a78266..40cfbad29 100644 --- a/source/luametatex/source/lua/lmtinterface.h +++ b/source/luametatex/source/lua/lmtinterface.h @@ -1456,6 +1456,7 @@ make_lua_key(L, void);\ make_lua_key(L, vrule);\ make_lua_key(L, vskip);\ make_lua_key(L, vtop);\ +make_lua_key(L, dbox);\ make_lua_key(L, whatsit);\ make_lua_key(L, widowpenalties);\ make_lua_key(L, widowpenalty);\ diff --git a/source/luametatex/source/lua/lmtnodelib.c b/source/luametatex/source/lua/lmtnodelib.c index cc7501786..5ad42124d 100644 --- a/source/luametatex/source/lua/lmtnodelib.c +++ b/source/luametatex/source/lua/lmtnodelib.c @@ -8133,7 +8133,6 @@ static int nodelib_userdata_instock(lua_State *L) return 2; } - /* node.usedlist */ static int nodelib_userdata_usedlist(lua_State *L) diff --git a/source/luametatex/source/lua/lmttexlib.c b/source/luametatex/source/lua/lmttexlib.c index 0d84eebdd..9c1247884 100644 --- a/source/luametatex/source/lua/lmttexlib.c +++ b/source/luametatex/source/lua/lmttexlib.c @@ -1144,7 +1144,7 @@ static int texlib_error(lua_State *L) */ -inline static int texlib_aux_valid_register_index(lua_State *L, int slot, int cmd, int base, int max) +inline static int texlib_aux_valid_register_index(lua_State *L, int slot, int cmd, int base, int max, int constant_cmd) { int index = -1; switch (lua_type(L, slot)) { @@ -1155,6 +1155,8 @@ inline static int texlib_aux_valid_register_index(lua_State *L, int slot, int cm int cs = tex_string_locate(str, len, 0); if (eq_type(cs) == cmd) { index = eq_value(cs) - base; + } else if (eq_type(cs) == constant_cmd) { + return 0xFFFF + cs; // way above max } } break; @@ -1167,6 +1169,8 @@ inline static int texlib_aux_valid_register_index(lua_State *L, int slot, int cm } if (index >= 0 && index <= max) { return index; + } else if (index < (eqtb_size + lmt_hash_state.hash_data.ptr + 1) && eq_type(index) == constant_cmd) { + return index; } else { return -1; } @@ -1194,9 +1198,9 @@ static int texlib_get_register_index(lua_State *L) return 1; } -inline static int texlib_aux_checked_register(lua_State *L, int cmd, int base, int max) +inline static int texlib_aux_checked_register(lua_State *L, int cmd, int base, int max, int constant_cmd) { - int index = texlib_aux_valid_register_index(L, 1, cmd, base, max); + int index = texlib_aux_valid_register_index(L, 1, cmd, base, max, constant_cmd); if (index >= 0) { lua_pushinteger(L, index); } else { @@ -1302,7 +1306,8 @@ static int texlib_aux_check_for_index( int register_cmd, int internal_base, int register_base, - int max_index + int max_index, + int constant_cmd ) { *index = -1; switch (lua_type(L, slot)) { @@ -1317,6 +1322,9 @@ static int texlib_aux_check_for_index( } else if (eq_type(cs) == register_cmd) { *index = eq_value(cs) - register_base; return 0; + } else if (eq_type(cs) == constant_cmd) { + *index = cs; + return 2; } else { luaL_error(L, "incorrect %s name", what); return -1; @@ -1326,9 +1334,14 @@ static int texlib_aux_check_for_index( *index = lmt_tointeger(L, slot); if (*index >= 0 && *index <= max_index) { return 0; - } else { - return -1; + } else { + halfword i = *index - 0xFFFF; + if (i < (eqtb_size + lmt_hash_state.hash_data.ptr + 1) && eq_type(i) == constant_cmd) { + *index = i; + return 2; + } } + return -1; default: luaL_error(L, "%s name or valid index expected", what); return -1; @@ -1347,7 +1360,7 @@ static int texlib_get(lua_State *L); static int texlib_isdimen(lua_State *L) { - return texlib_aux_checked_register(L, register_dimen_cmd, register_dimen_base, max_dimen_register_index); + return texlib_aux_checked_register(L, register_dimen_cmd, register_dimen_base, max_dimen_register_index, dimension_cmd); } /* [global] name|index integer|dimension|false|nil */ @@ -1357,7 +1370,7 @@ static int texlib_setdimen(lua_State *L) int flags = 0; int index = 0; int slot = lmt_check_for_flags(L, 1, &flags, 1, 0); - int state = texlib_aux_check_for_index(L, slot++, "dimen", &index, internal_dimen_cmd, register_dimen_cmd, internal_dimen_base, register_dimen_base, max_dimen_register_index); + int state = texlib_aux_check_for_index(L, slot++, "dimen", &index, internal_dimen_cmd, register_dimen_cmd, internal_dimen_base, register_dimen_base, max_dimen_register_index, dimension_cmd); if (state >= 0) { halfword value = 0; switch (lua_type(L, slot)) { @@ -1380,9 +1393,13 @@ static int texlib_setdimen(lua_State *L) luaL_error(L, "unsupported dimen value type"); break; } - tex_set_tex_dimen_register(index, value, flags, state); - if (state == 1 && lua_toboolean(L, slot)) { - tex_update_par_par(internal_dimen_cmd, index); + if (state == 2) { + tex_define(flags, index, dimension_cmd, value); + } else { + tex_set_tex_dimen_register(index, value, flags, state); + if (state == 1 && lua_toboolean(L, slot)) { + tex_update_par_par(internal_dimen_cmd, index); + } } } return 0; @@ -1391,8 +1408,16 @@ static int texlib_setdimen(lua_State *L) static int texlib_getdimen(lua_State *L) { int index; - int state = texlib_aux_check_for_index(L, 1, "dimen", &index, internal_dimen_cmd, register_dimen_cmd, internal_dimen_base, register_dimen_base, max_dimen_register_index); - lua_pushinteger(L, state >= 0 ? tex_get_tex_dimen_register(index, state) : 0); + int state = texlib_aux_check_for_index(L, 1, "dimen", &index, internal_dimen_cmd, register_dimen_cmd, internal_dimen_base, register_dimen_base, max_dimen_register_index, dimension_cmd); + lua_pushinteger(L, state >= 0 ? (state == 2 ? eq_value(index) : tex_get_tex_dimen_register(index, state)) : 0); + // halfword value; + // switch (state) { + // case 0 : value = dimen_parameter(index); break; + // case 1 : value = dimen_parameter(index); break; + // case 2 : value = eq_value(index); break; + // default: value = 0; + // } + // lua_pushinteger(L, value); return 1; } @@ -1459,7 +1484,7 @@ static halfword texlib_aux_get_glue_spec(lua_State *L, int slot) static int texlib_isskip(lua_State *L) { - return texlib_aux_checked_register(L, register_glue_cmd, register_glue_base, max_glue_register_index); + return texlib_aux_checked_register(L, register_glue_cmd, register_glue_base, max_glue_register_index, gluespec_cmd); } /* [global] name|index gluespec|false|nil */ @@ -1469,13 +1494,17 @@ static int texlib_setskip(lua_State *L) int flags = 0; int index = 0; int slot = lmt_check_for_flags(L, 1, &flags, 1, 0); - int state = texlib_aux_check_for_index(L, slot++, "skip", &index, internal_glue_cmd, register_glue_cmd, internal_glue_base, register_glue_base, max_glue_register_index); + int state = texlib_aux_check_for_index(L, slot++, "skip", &index, internal_glue_cmd, register_glue_cmd, internal_glue_base, register_glue_base, max_glue_register_index, gluespec_cmd); if (state >= 0) { - halfword value = texlib_aux_get_glue_spec(L, slot++); - tex_set_tex_skip_register(index, value, flags, state); - if (state == 1 && lua_toboolean(L, slot)) { - tex_update_par_par(internal_glue_cmd, index); - } + halfword value = texlib_aux_get_glue_spec(L, slot++); + if (state == 2) { + tex_define(flags, index, gluespec_cmd, value); + } else { + tex_set_tex_skip_register(index, value, flags, state); + if (state == 1 && lua_toboolean(L, slot)) { + tex_update_par_par(internal_glue_cmd, index); + } + } } return 0; } @@ -1483,15 +1512,15 @@ static int texlib_setskip(lua_State *L) static int texlib_getskip(lua_State *L) { int index; - int state = texlib_aux_check_for_index(L, 1, "skip", &index, internal_glue_cmd, register_glue_cmd, internal_glue_base, register_glue_base, max_glue_register_index); - halfword value = state >= 0 ? tex_get_tex_skip_register(index, state) : null; + int state = texlib_aux_check_for_index(L, 1, "skip", &index, internal_glue_cmd, register_glue_cmd, internal_glue_base, register_glue_base, max_glue_register_index, gluespec_cmd); + halfword value = state >= 0 ? (state == 2 ? eq_value(index) : tex_get_tex_skip_register(index, state)) : null; lmt_push_node_fast(L, tex_copy_node(value ? value : zero_glue)); return 1; } static int texlib_isglue(lua_State *L) { - return texlib_aux_checked_register(L, register_glue_cmd, register_glue_base, max_glue_register_index); + return texlib_aux_checked_register(L, register_glue_cmd, register_glue_base, max_glue_register_index, gluespec_cmd); } /* [global] slot [width] [stretch] [shrink] [stretch_order] [shrink_order] */ @@ -1501,9 +1530,14 @@ static int texlib_setglue(lua_State *L) int flags = 0; int index = 0; int slot = lmt_check_for_flags(L, 1, &flags, 1, 0); - int state = texlib_aux_check_for_index(L, slot++, "skip", &index, internal_glue_cmd, register_glue_cmd, internal_glue_base, register_glue_base, max_glue_register_index); + int state = texlib_aux_check_for_index(L, slot++, "skip", &index, internal_glue_cmd, register_glue_cmd, internal_glue_base, register_glue_base, max_glue_register_index, gluespec_cmd); if (state >= 0) { - tex_set_tex_skip_register(index, texlib_aux_make_glue(L, lua_gettop(L), slot), flags, state); + halfword value = texlib_aux_make_glue(L, lua_gettop(L), slot); + if (state == 2) { + tex_define(flags, index, gluespec_cmd, value); + } else { + tex_set_tex_skip_register(index, value, flags, state); + } } return 0; } @@ -1512,8 +1546,8 @@ static int texlib_getglue(lua_State *L) { int index; int all = (lua_type(L, 2) == LUA_TBOOLEAN) ? lua_toboolean(L, 2) : 1; - int state = texlib_aux_check_for_index(L, 1, "skip", &index, internal_glue_cmd, register_glue_cmd, internal_glue_base, register_glue_base, max_glue_register_index); - halfword value = state >= 0 ? tex_get_tex_skip_register(index, state) : null; + int state = texlib_aux_check_for_index(L, 1, "skip", &index, internal_glue_cmd, register_glue_cmd, internal_glue_base, register_glue_base, max_glue_register_index, gluespec_cmd); + halfword value = state >= 0 ? (state == 2 ? eq_value(index) : tex_get_tex_skip_register(index, state)) : null; if (! value) { lua_pushinteger(L, 0); if (all) { @@ -1535,7 +1569,7 @@ static int texlib_getglue(lua_State *L) static int texlib_ismuskip(lua_State *L) { - return texlib_aux_checked_register(L, register_mu_glue_cmd, register_mu_glue_base, max_mu_glue_register_index); + return texlib_aux_checked_register(L, register_mu_glue_cmd, register_mu_glue_base, max_mu_glue_register_index, mugluespec_cmd); } static int texlib_setmuskip(lua_State *L) @@ -1543,23 +1577,30 @@ static int texlib_setmuskip(lua_State *L) int flags = 0; int index = 0; int slot = lmt_check_for_flags(L, 1, &flags, 1, 0); - int state = texlib_aux_check_for_index(L, slot++, "muskip", &index, internal_mu_glue_cmd, register_mu_glue_cmd, internal_mu_glue_base, register_mu_glue_base, max_mu_glue_register_index); - tex_set_tex_mu_skip_register(index, texlib_aux_get_glue_spec(L, slot), flags, state); + int state = texlib_aux_check_for_index(L, slot++, "muskip", &index, internal_mu_glue_cmd, register_mu_glue_cmd, internal_mu_glue_base, register_mu_glue_base, max_mu_glue_register_index, mugluespec_cmd); + if (state >= 0) { + halfword value =texlib_aux_get_glue_spec(L, slot); + if (state == 2) { + tex_define(flags, index, mugluespec_cmd, value); + } else { + tex_set_tex_mu_skip_register(index, value, flags, state); + } + } return 0; } static int texlib_getmuskip(lua_State *L) { int index; - int state = texlib_aux_check_for_index(L, 1, "muskip", &index, internal_mu_glue_cmd, register_mu_glue_cmd, internal_mu_glue_base, register_mu_glue_base, max_mu_glue_register_index); - halfword value = state >= 0 ? tex_get_tex_mu_skip_register(index, state) : null; + int state = texlib_aux_check_for_index(L, 1, "muskip", &index, internal_mu_glue_cmd, register_mu_glue_cmd, internal_mu_glue_base, register_mu_glue_base, max_mu_glue_register_index, mugluespec_cmd); + halfword value = state >= 0 ? (state == 2 ? eq_value(index) : tex_get_tex_mu_skip_register(index, state)) : null; lmt_push_node_fast(L, tex_copy_node(value ? value : zero_glue)); return 1; } static int texlib_ismuglue(lua_State *L) { - return texlib_aux_checked_register(L, register_mu_glue_cmd, register_mu_glue_base, max_mu_glue_register_index); + return texlib_aux_checked_register(L, register_mu_glue_cmd, register_mu_glue_base, max_mu_glue_register_index, mugluespec_cmd); } static int texlib_setmuglue(lua_State *L) @@ -1567,10 +1608,14 @@ static int texlib_setmuglue(lua_State *L) int flags = 0; int index = 0; int slot = lmt_check_for_flags(L, 1, &flags, 1, 0); - int state = texlib_aux_check_for_index(L, slot++, "muskip", &index, internal_mu_glue_cmd, register_mu_glue_cmd, internal_mu_glue_base, register_mu_glue_base, max_mu_glue_register_index); - halfword value = texlib_aux_make_glue(L, lua_gettop(L), slot); + int state = texlib_aux_check_for_index(L, slot++, "muskip", &index, internal_mu_glue_cmd, register_mu_glue_cmd, internal_mu_glue_base, register_mu_glue_base, max_mu_glue_register_index, mugluespec_cmd); if (state >= 0) { - tex_set_tex_mu_skip_register(index, value, flags, state); + halfword value = texlib_aux_make_glue(L, lua_gettop(L), slot); + if (state == 2) { + tex_define(flags, index, mugluespec_cmd, value); + } else { + tex_set_tex_mu_skip_register(index, value, flags, state); + } } return 0; } @@ -1579,8 +1624,8 @@ static int texlib_getmuglue(lua_State *L) { int index; int all = (lua_type(L, 2) == LUA_TBOOLEAN) ? lua_toboolean(L, 2) : 1; - int state = texlib_aux_check_for_index(L, 1, "muskip", &index, internal_mu_glue_cmd, register_mu_glue_cmd, internal_mu_glue_base, register_mu_glue_base, max_mu_glue_register_index); - halfword value = state >= 0 ? tex_get_tex_mu_skip_register(index, state) : null; + int state = texlib_aux_check_for_index(L, 1, "muskip", &index, internal_mu_glue_cmd, register_mu_glue_cmd, internal_mu_glue_base, register_mu_glue_base, max_mu_glue_register_index, mugluespec_cmd); + halfword value = state >= 0 ? (state == 2 ? eq_value(index) : tex_get_tex_mu_skip_register(index, state)) : null; if (! value) { lua_pushinteger(L, 0); return 1; @@ -1595,7 +1640,7 @@ static int texlib_getmuglue(lua_State *L) static int texlib_iscount(lua_State *L) { - return texlib_aux_checked_register(L, register_int_cmd, register_int_base, max_int_register_index); + return texlib_aux_checked_register(L, register_int_cmd, register_int_base, max_int_register_index, integer_cmd); } static int texlib_setcount(lua_State *L) @@ -1603,12 +1648,16 @@ static int texlib_setcount(lua_State *L) int flags = 0; int index = 0; int slot = lmt_check_for_flags(L, 1, &flags, 1, 0); - int state = texlib_aux_check_for_index(L, slot++, "count", &index, internal_int_cmd, register_int_cmd, internal_int_base, register_int_base, max_int_register_index); + int state = texlib_aux_check_for_index(L, slot++, "count", &index, internal_int_cmd, register_int_cmd, internal_int_base, register_int_base, max_int_register_index, integer_cmd); if (state >= 0) { halfword value = lmt_optinteger(L, slot++, 0); - tex_set_tex_count_register(index, value, flags, state); - if (state == 1 && lua_toboolean(L, slot)) { - tex_update_par_par(internal_int_cmd, index); + if (state == 2) { + tex_define(flags, index, integer_cmd, value); + } else { + tex_set_tex_count_register(index, value, flags, state); + if (state == 1 && lua_toboolean(L, slot)) { + tex_update_par_par(internal_int_cmd, index); + } } } return 0; @@ -1617,14 +1666,14 @@ static int texlib_setcount(lua_State *L) static int texlib_getcount(lua_State *L) { int index; - int state = texlib_aux_check_for_index(L, 1, "count", &index, internal_int_cmd, register_int_cmd, internal_int_base, register_int_base, max_int_register_index); - lua_pushinteger(L, state >= 0 ? tex_get_tex_count_register(index, state) : 0); + int state = texlib_aux_check_for_index(L, 1, "count", &index, internal_int_cmd, register_int_cmd, internal_int_base, register_int_base, max_int_register_index, integer_cmd); + lua_pushinteger(L, state >= 0 ? (state == 2 ? eq_value(index) : tex_get_tex_count_register(index, state)) : 0); return 1; } static int texlib_isattribute(lua_State *L) { - return texlib_aux_checked_register(L, register_attribute_cmd, register_attribute_base, max_attribute_register_index); + return texlib_aux_checked_register(L, register_attribute_cmd, register_attribute_base, max_attribute_register_index, -1); } /*tex there are no system set attributes so this is a bit overkill */ @@ -1634,7 +1683,7 @@ static int texlib_setattribute(lua_State *L) int flags = 0; int index = 0; int slot = lmt_check_for_flags(L, 1, &flags, 1, 0); - int state = texlib_aux_check_for_index(L, slot++, "attribute", &index, internal_attribute_cmd, register_attribute_cmd, internal_attribute_base, register_attribute_base, max_attribute_register_index); + int state = texlib_aux_check_for_index(L, slot++, "attribute", &index, internal_attribute_cmd, register_attribute_cmd, internal_attribute_base, register_attribute_base, max_attribute_register_index, 0); if (state >= 0) { halfword value = lmt_optinteger(L, slot++, unused_attribute_value); tex_set_tex_attribute_register(index, value, flags, state); @@ -1645,7 +1694,7 @@ static int texlib_setattribute(lua_State *L) static int texlib_getattribute(lua_State *L) { int index; - int state = texlib_aux_check_for_index(L, 1, "attribute", &index, internal_attribute_cmd, register_attribute_cmd, internal_attribute_base, register_attribute_base, max_attribute_register_index); + int state = texlib_aux_check_for_index(L, 1, "attribute", &index, internal_attribute_cmd, register_attribute_cmd, internal_attribute_base, register_attribute_base, max_attribute_register_index, 0); lua_pushinteger(L, state >= 0 ? tex_get_tex_attribute_register(index, state) : 0); return 1; } @@ -1656,7 +1705,7 @@ static int texlib_getattribute(lua_State *L) static int texlib_istoks(lua_State *L) { - return texlib_aux_checked_register(L, register_toks_cmd, register_toks_base, max_toks_register_index); + return texlib_aux_checked_register(L, register_toks_cmd, register_toks_base, max_toks_register_index, -1); } /* [global] name|integer string|nil */ @@ -1666,7 +1715,7 @@ static int texlib_settoks(lua_State *L) int flags = 0; int index = 0; int slot = lmt_check_for_flags(L, 1, &flags, 1, 0); - int state = texlib_aux_check_for_index(L, slot++, "toks", &index, internal_toks_cmd, register_toks_cmd, internal_toks_base, register_toks_base,max_toks_register_index); + int state = texlib_aux_check_for_index(L, slot++, "toks", &index, internal_toks_cmd, register_toks_cmd, internal_toks_base, register_toks_base,max_toks_register_index, 0); if (state >= 0) { lstring value = { .c = NULL, .l = 0 }; switch (lua_type(L, slot)) { @@ -1691,7 +1740,7 @@ static int texlib_scantoks(lua_State *L) // TODO int index = 0; int flags = 0; int slot = lmt_check_for_flags(L, 1, &flags, 1, 0); - int state = texlib_aux_check_for_index(L, slot++, "toks", &index, internal_toks_cmd, register_toks_cmd, internal_toks_base, register_toks_base,max_toks_register_index); + int state = texlib_aux_check_for_index(L, slot++, "toks", &index, internal_toks_cmd, register_toks_cmd, internal_toks_base, register_toks_base,max_toks_register_index, 0); if (state >= 0) { lstring value = { .c = NULL, .l = 0 }; int cattable = lmt_checkinteger(L, slot++); @@ -1714,7 +1763,7 @@ static int texlib_gettoks(lua_State *L) { int index; int slot = 1; - int state = texlib_aux_check_for_index(L, slot++, "toks", &index, internal_toks_cmd, register_toks_cmd, internal_toks_base, register_toks_base, max_toks_register_index); + int state = texlib_aux_check_for_index(L, slot++, "toks", &index, internal_toks_cmd, register_toks_cmd, internal_toks_base, register_toks_base, max_toks_register_index, 0); if (state >= 0) { if (lua_toboolean(L, slot)) { lmt_token_register_to_lua(L, state ? toks_parameter(index) : toks_register(index)); diff --git a/source/luametatex/source/lua/lmttokenlib.c b/source/luametatex/source/lua/lmttokenlib.c index 41ee6c485..c591bd7f6 100644 --- a/source/luametatex/source/lua/lmttokenlib.c +++ b/source/luametatex/source/lua/lmttokenlib.c @@ -2952,11 +2952,13 @@ static int tokenlib_scan_box(lua_State *L) const char *s = lua_tostring(L, 1); halfword code = -1 ; if (lua_key_eq(s, hbox)) { - code = vtop_code + hmode; + code = hbox_code; } else if (lua_key_eq(s, vbox)) { - code = vtop_code + vmode; + code = vbox_code; } else if (lua_key_eq(s, vtop)) { code = vtop_code; + } else if (lua_key_eq(s, dbox)) { + code = dbox_code; } if (code >= 0) { tex_back_input(token_val(make_box_cmd, code)); diff --git a/source/luametatex/source/luametatex.h b/source/luametatex/source/luametatex.h index 973b405ae..c92599fbc 100644 --- a/source/luametatex/source/luametatex.h +++ b/source/luametatex/source/luametatex.h @@ -89,7 +89,7 @@ # define luametatex_version 210 # define luametatex_revision 04 # define luametatex_version_string "2.10.04" -# define luametatex_development_id 20221214 +# define luametatex_development_id 20221221 # define luametatex_name_camelcase "LuaMetaTeX" # define luametatex_name_lowercase "luametatex" diff --git a/source/luametatex/source/tex/texcommands.c b/source/luametatex/source/tex/texcommands.c index 0ad91e420..eeef6b9f6 100644 --- a/source/luametatex/source/tex/texcommands.c +++ b/source/luametatex/source/tex/texcommands.c @@ -316,6 +316,11 @@ void tex_initialize_commands(void) tex_primitive(tex_command, "advance", arithmic_cmd, advance_code, 0); tex_primitive(tex_command, "divide", arithmic_cmd, divide_code, 0); tex_primitive(tex_command, "multiply", arithmic_cmd, multiply_code, 0); + tex_primitive(tex_command, "advanceby", arithmic_cmd, advance_by_code, 0); + tex_primitive(tex_command, "divideby", arithmic_cmd, divide_by_code, 0); + tex_primitive(tex_command, "multiplyby", arithmic_cmd, multiply_by_code, 0); + /* tex_primitive(tex_command, "advancebyplusone", arithmic_cmd, advance_by_plus_one_code, 0); */ + /* tex_primitive(tex_command, "advancebyminusone", arithmic_cmd, advance_by_minus_one_code, 0); */ /*tex We combined the after thingies into one category:*/ @@ -877,9 +882,11 @@ void tex_initialize_commands(void) tex_primitive(luatex_command, "tpack", make_box_cmd, tpack_code, 0); tex_primitive(luatex_command, "vpack", make_box_cmd, vpack_code, 0); tex_primitive(luatex_command, "hpack", make_box_cmd, hpack_code, 0); + tex_primitive(luatex_command, "dpack", make_box_cmd, dpack_code, 0); tex_primitive(tex_command, "vtop", make_box_cmd, vtop_code, 0); tex_primitive(tex_command, "vbox", make_box_cmd, vbox_code, 0); tex_primitive(tex_command, "hbox", make_box_cmd, hbox_code, 0); + tex_primitive(luatex_command, "dbox", make_box_cmd, dbox_code, 0); tex_primitive(luatex_command, "insertbox", make_box_cmd, insert_box_code, 0); tex_primitive(luatex_command, "insertcopy", make_box_cmd, insert_copy_code, 0); tex_primitive(luatex_command, "localleftboxbox", make_box_cmd, local_left_box_box_code, 0); @@ -985,7 +992,7 @@ void tex_initialize_commands(void) tex_primitive(tex_command, "muskipdef", shorthand_def_cmd, mu_skip_def_code, 0); tex_primitive(tex_command, "skipdef", shorthand_def_cmd, skip_def_code, 0); tex_primitive(tex_command, "toksdef", shorthand_def_cmd, toks_def_code, 0); - /* tex_primitive(tex_command, "stringdef", shorthand_def_cmd, string_def_code, 0); */ + /* tex_primitive(luatex_command, "stringdef", shorthand_def_cmd, string_def_code, 0); */ tex_primitive(luatex_command, "Umathchardef", shorthand_def_cmd, math_xchar_def_code, 0); tex_primitive(luatex_command, "Umathdictdef", shorthand_def_cmd, math_dchar_def_code, 0); tex_primitive(luatex_command, "attributedef", shorthand_def_cmd, attribute_def_code, 0); @@ -996,6 +1003,8 @@ void tex_initialize_commands(void) tex_primitive(luatex_command, "mugluespecdef", shorthand_def_cmd, mugluespec_def_code, 0); /* tex_primitive(luatex_command, "mathspecdef", shorthand_def_cmd, mathspec_def_code, 0); */ tex_primitive(luatex_command, "fontspecdef", shorthand_def_cmd, fontspec_def_code, 0); + /* tex_primitive(luatex_command, "integerdefcsname", shorthand_def_cmd, integer_def_csname_code, 0); */ + /* tex_primitive(luatex_command, "dimensiondefcsname", shorthand_def_cmd, dimension_def_csname_code, 0); */ tex_primitive(tex_command, "noindent", begin_paragraph_cmd, noindent_par_code, 0); tex_primitive(tex_command, "indent", begin_paragraph_cmd, indent_par_code, 0); diff --git a/source/luametatex/source/tex/texcommands.h b/source/luametatex/source/tex/texcommands.h index 8df61a4db..be0639af7 100644 --- a/source/luametatex/source/tex/texcommands.h +++ b/source/luametatex/source/tex/texcommands.h @@ -334,7 +334,7 @@ typedef enum tex_command_code { # define is_referenced_cmd(cmd) (cmd >= call_cmd) # define is_nodebased_cmd(cmd) (cmd >= gluespec_cmd && cmd <= fontspec_cmd) - +# define is_constant_cmd(cmd) (cmd >= integer_cmd && cmd <= gluespec_cmd) # if (main_control_mode == 1) @@ -362,10 +362,15 @@ typedef enum arithmic_codes { advance_code, multiply_code, divide_code, + advance_by_code, + multiply_by_code, + divide_by_code, /* bitwise_and_code, */ /* bitwise_xor_code, */ /* bitwise_or_code, */ /* bitwise_not_code, */ + /* advance_by_plus_one_code, */ + /* advance_by_minus_one_code, */ } arithmic_codes; # define last_arithmic_code divide_code @@ -690,6 +695,8 @@ typedef enum shorthand_def_codes { mugluespec_def_code, /* mathspec_def_code, */ fontspec_def_code, + /* integer_def_csname_code, */ + /* dimension_def_csname_code, */ } shorthand_def_codes; # define last_shorthand_def_code fontspec_def_code diff --git a/source/luametatex/source/tex/texdumpdata.h b/source/luametatex/source/tex/texdumpdata.h index 4f3450ef4..6a9eb5fa4 100644 --- a/source/luametatex/source/tex/texdumpdata.h +++ b/source/luametatex/source/tex/texdumpdata.h @@ -55,7 +55,7 @@ */ -# define luametatex_format_fingerprint 679 +# define luametatex_format_fingerprint 680 /* These end up in the string pool. */ diff --git a/source/luametatex/source/tex/texequivalents.c b/source/luametatex/source/tex/texequivalents.c index 223e46e15..d91663dd3 100644 --- a/source/luametatex/source/tex/texequivalents.c +++ b/source/luametatex/source/tex/texequivalents.c @@ -569,6 +569,9 @@ void tex_show_save_groups(void) case vtop_group: package = "vtop"; break; + case dbox_group: + package = "dbox"; + break; case align_group: if (alignmentstate == 0) { package = (mode == -vmode) ? "halign" : "valign"; @@ -1176,6 +1179,37 @@ void tex_define(int g, halfword p, singleword t, halfword e) /* int g -> singlew } } +void tex_define_again(int g, halfword p, singleword t, halfword e) /* int g -> singleword g */ +{ + if (tracing_assigns_par > 0) { + singleword f = make_eq_flag_bits(g); + if (is_global(g)) { + /* what if already global */ + tex_aux_diagnostic_trace(p, "globally changing"); + // if (tex_aux_equal_eq(p, t, f, e) && (eq_level(p) == level_one)) { + // return; /* we can save some stack */ + // } + tex_aux_eq_destroy(lmt_hash_state.eqtb[p]); + tex_aux_set_eq_data(p, t, e, f, level_one); + } else if (tex_aux_equal_eq(p, t, f, e)) { + /* hm, we tweak the ref ! */ + tex_aux_diagnostic_trace(p, "reassigning"); + } else { + tex_aux_diagnostic_trace(p, "changing"); + if (eq_level(p) == cur_level) { + tex_aux_eq_destroy(lmt_hash_state.eqtb[p]); + } else if (cur_level > level_one) { + tex_aux_eq_save(p, eq_level(p)); + } + tex_aux_set_eq_data(p, t, e, f, cur_level); + } + tex_aux_diagnostic_trace(p, "into"); + } else { + set_eq_type(p, t); + set_eq_value(p, e); + } +} + void tex_define_inherit(int g, halfword p, singleword f, singleword t, halfword e) { int trace = tracing_assigns_par > 0; diff --git a/source/luametatex/source/tex/texequivalents.h b/source/luametatex/source/tex/texequivalents.h index c84b90226..511463c6a 100644 --- a/source/luametatex/source/tex/texequivalents.h +++ b/source/luametatex/source/tex/texequivalents.h @@ -719,7 +719,10 @@ typedef enum attribute_codes { # define internal_specification_location(a) (internal_specification_base + (a)) # define internal_specification_number(a) ((a) - internal_specification_base) -# define eqtb_size (internal_specification_base + number_specification_pars) +# define eqtb_size (internal_specification_base + number_specification_pars) +# define eqtb_max_so_far (eqtb_size + lmt_hash_state.hash_data.ptr + 1) + +/* below: top or ptr +1 ? */ # define eqtb_indirect_range(n) ((n < internal_glue_base) || ((n > eqtb_size) && (n <= lmt_hash_state.hash_data.top))) # define eqtb_out_of_range(n) ((n >= undefined_control_sequence) && ((n <= eqtb_size) || n > lmt_hash_state.hash_data.top)) @@ -968,6 +971,7 @@ typedef enum tex_group_codes { adjusted_hbox_group, /*tex code for |\hbox| in vertical mode */ vbox_group, /*tex code for |\vbox| */ vtop_group, /*tex code for |\vtop| */ + dbox_group, /*tex code for |\dbox| */ align_group, /*tex code for |\halign|, |\valign| */ no_align_group, /*tex code for |\noalign| */ output_group, /*tex code for output routine */ @@ -1012,6 +1016,7 @@ typedef enum tex_par_context_codes { vmode_par_context, vbox_par_context, vtop_par_context, + dbox_par_context, vcenter_par_context, vadjust_par_context, insert_par_context, @@ -1257,6 +1262,7 @@ inline static singleword tex_flags_to_cmd(int flags) extern int tex_define_permitted (halfword cs, halfword prefixes); extern void tex_define (int g, halfword p, singleword cmd, halfword chr); +extern void tex_define_again (int g, halfword p, singleword cmd, halfword chr); extern void tex_define_inherit (int g, halfword p, singleword flag, singleword cmd, halfword chr); extern void tex_define_swapped (int g, halfword p1, halfword p2, int force); extern void tex_forced_define (int g, halfword p, singleword flag, singleword cmd, halfword chr); diff --git a/source/luametatex/source/tex/texmaincontrol.c b/source/luametatex/source/tex/texmaincontrol.c index dbb52ab15..aa160968e 100644 --- a/source/luametatex/source/tex/texmaincontrol.c +++ b/source/luametatex/source/tex/texmaincontrol.c @@ -2487,7 +2487,7 @@ static void tex_aux_extra_right_brace_error(void) inline static void tex_aux_finish_hbox(void) { tex_aux_fixup_directions_only(); - tex_package(hpack_code); + tex_package(hbox_code); } inline static void tex_aux_finish_adjusted_hbox(void) @@ -2496,14 +2496,14 @@ inline static void tex_aux_finish_adjusted_hbox(void) lmt_packaging_state.pre_adjust_tail = pre_adjust_head; lmt_packaging_state.post_migrate_tail = post_migrate_head; lmt_packaging_state.pre_migrate_tail = pre_migrate_head; - tex_package(hpack_code); + tex_package(hbox_code); } inline static void tex_aux_finish_vbox(void) { if (! tex_wrapped_up_paragraph(vbox_par_context)) { tex_end_paragraph(vbox_group, vbox_par_context); - tex_package(vpack_code); + tex_package(vbox_code); } } @@ -2515,6 +2515,14 @@ inline static void tex_aux_finish_vtop(void) } } +inline static void tex_aux_finish_dbox(void) +{ + if (! tex_wrapped_up_paragraph(dbox_par_context)) { + tex_end_paragraph(dbox_group, dbox_par_context); + tex_package(dbox_code); + } +} + inline static void tex_aux_finish_simple_group(void) { tex_aux_fixup_directions_and_unsave(); @@ -2557,6 +2565,9 @@ static void tex_aux_run_right_brace(void) case vtop_group: tex_aux_finish_vtop(); break; + case dbox_group: + tex_aux_finish_dbox(); + break; case align_group: tex_finish_alignment_group(); break; @@ -3538,40 +3549,71 @@ inline static halfword tex_aux_get_register_value(int level, int optionalequal) } } -static int tex_aux_valid_arithmic(int cmd, int *index, int *level, int *varcmd) +static int tex_aux_valid_arithmic(int cmd, int *index, int *level, int *varcmd, int *simple, int *original) { /*tex So: |\multiply|, |\divide| or |\advance|. */ tex_get_x_token(); *varcmd = cur_cmd; + /* *simple = 0; */ switch (cur_cmd) { case register_int_cmd: case internal_int_cmd: *index = cur_chr; *level = int_val_level; + *original = eq_value(*index); return 1; case register_attribute_cmd: case internal_attribute_cmd: *index = cur_chr; *level = attr_val_level; + *original = eq_value(*index); return 1; case register_dimen_cmd: case internal_dimen_cmd: *index = cur_chr; *level = dimen_val_level; + *original = eq_value(*index); return 1; case register_glue_cmd: case internal_glue_cmd: *index = cur_chr; *level = glue_val_level; + *original = eq_value(*index); return 1; case register_mu_glue_cmd: case internal_mu_glue_cmd: *index = cur_chr; *level = mu_val_level; + *original = eq_value(*index); return 1; case register_cmd: - *level = cur_chr; *index = tex_aux_get_register_index(*level); + *level = cur_chr; + *original = eq_value(*index); + return 1; + case integer_cmd: + *index = cur_cs; + *level = int_val_level; + *original = cur_chr; + *simple = integer_cmd; + return 1; + case dimension_cmd: + *index = cur_cs; + *level = dimen_val_level; + *original = cur_chr; + *simple = dimension_cmd; + return 1; + case gluespec_cmd: + *index = cur_cs; + *level = glue_val_level; + *original = cur_chr; + *simple = gluespec_cmd; + return 1; + case mugluespec_cmd: + *index = cur_cs; + *level = mu_val_level; + *original = cur_chr; + *simple = mugluespec_cmd; return 1; default: tex_handle_error( @@ -3635,7 +3677,7 @@ inline static void tex_aux_update_register(int a, int level, halfword index, hal } } -static void tex_aux_set_register(int a) +inline static void tex_aux_set_register(int a) { halfword level = cur_chr; halfword varcmd = cur_cmd; @@ -3644,51 +3686,60 @@ static void tex_aux_set_register(int a) tex_aux_update_register(a, level, index, value, varcmd); } +/*tex + The by-less variant is more efficient as there is no push back of the token when there is not + such keyword. It goes unnoticed on an average run but not on the total runtime of 15.000 + (times 2) runs of a 30 page \CONTEXT\ document with plenty of complex tables. So this is one + of the few obscure optimizations I grand myself (if only to be able to discuss it). +*/ + static void tex_aux_arithmic_register(int a, int code) { halfword cmd = cur_cmd; halfword level = cur_chr; halfword index = 0; halfword varcmd = 0; - if (tex_aux_valid_arithmic(cmd, &index, &level, &varcmd)) { + halfword simple = 0; + halfword original = 0; + if (tex_aux_valid_arithmic(cmd, &index, &level, &varcmd, &simple, &original)) { halfword value = null; - tex_scan_optional_keyword("by"); lmt_scanner_state.arithmic_error = 0; switch (code) { case advance_code: + tex_scan_optional_keyword("by"); + case advance_by_code: { value = tex_aux_get_register_value(level, 0); switch (level) { case int_val_level: case attr_val_level: case dimen_val_level: - value += eq_value(index); + value += original; break; case glue_val_level: case mu_val_level: { /* Compute the sum of two glue specs */ - halfword oldvalue = eq_value(index); halfword newvalue = tex_new_glue_spec_node(value); tex_flush_node(value); - glue_amount(newvalue) += glue_amount(oldvalue); + glue_amount(newvalue) += glue_amount(original); if (glue_stretch(newvalue) == 0) { glue_stretch_order(newvalue) = normal_glue_order; } - if (glue_stretch_order(newvalue) == glue_stretch_order(oldvalue)) { - glue_stretch(newvalue) += glue_stretch(oldvalue); - } else if ((glue_stretch_order(newvalue) < glue_stretch_order(oldvalue)) && (glue_stretch(oldvalue))) { - glue_stretch(newvalue) = glue_stretch(oldvalue); - glue_stretch_order(newvalue) = glue_stretch_order(oldvalue); + if (glue_stretch_order(newvalue) == glue_stretch_order(original)) { + glue_stretch(newvalue) += glue_stretch(original); + } else if ((glue_stretch_order(newvalue) < glue_stretch_order(original)) && (glue_stretch(original))) { + glue_stretch(newvalue) = glue_stretch(original); + glue_stretch_order(newvalue) = glue_stretch_order(original); } if (glue_shrink(newvalue) == 0) { glue_shrink_order(newvalue) = normal_glue_order; } - if (glue_shrink_order(newvalue) == glue_shrink_order(oldvalue)) { - glue_shrink(newvalue) += glue_shrink(oldvalue); - } else if ((glue_shrink_order(newvalue) < glue_shrink_order(oldvalue)) && (glue_shrink(oldvalue))) { - glue_shrink(newvalue) = glue_shrink(oldvalue); - glue_shrink_order(newvalue) = glue_shrink_order(oldvalue); + if (glue_shrink_order(newvalue) == glue_shrink_order(original)) { + glue_shrink(newvalue) += glue_shrink(original); + } else if ((glue_shrink_order(newvalue) < glue_shrink_order(original)) && (glue_shrink(original))) { + glue_shrink(newvalue) = glue_shrink(original); + glue_shrink_order(newvalue) = glue_shrink_order(original); } value = newvalue; break; @@ -3698,29 +3749,34 @@ static void tex_aux_arithmic_register(int a, int code) break; } /*tex There is no overflow detection for addition, just wraparound. */ - tex_aux_update_register(a, level, index, value, varcmd); + if (simple) { + tex_define(a, index, simple, value); + } else { + tex_aux_update_register(a, level, index, value, varcmd); + } break; } case multiply_code: + tex_scan_optional_keyword("by"); + case multiply_by_code: { halfword amount = tex_scan_int(0, NULL); switch (level) { case int_val_level: case attr_val_level: - value = tex_multiply_integers(eq_value(index), amount); + value = tex_multiply_integers(original, amount); break; case dimen_val_level: - value = tex_nx_plus_y(eq_value(index), amount, 0); + value = tex_nx_plus_y(original, amount, 0); break; case glue_val_level: case mu_val_level: { - halfword s = eq_value(index); - halfword r = tex_new_glue_spec_node(s); - glue_amount(r) = tex_nx_plus_y(glue_amount(s), amount, 0); - glue_stretch(r) = tex_nx_plus_y(glue_stretch(s), amount, 0); - glue_shrink(r) = tex_nx_plus_y(glue_shrink(s), amount, 0); - value = r; + halfword newvalue = tex_new_glue_spec_node(original); + glue_amount(newvalue) = tex_nx_plus_y(glue_amount(original), amount, 0); + glue_stretch(newvalue) = tex_nx_plus_y(glue_stretch(original), amount, 0); + glue_shrink(newvalue) = tex_nx_plus_y(glue_shrink(original), amount, 0); + value = newvalue; break; } default: @@ -3729,29 +3785,32 @@ static void tex_aux_arithmic_register(int a, int code) } if (lmt_scanner_state.arithmic_error) { tex_aux_arithmic_overflow_error(level, value); + } else if (simple) { + tex_define(a, index, simple, value); } else { tex_aux_update_register(a, level, index, value, varcmd); } break; } case divide_code: + tex_scan_optional_keyword("by"); + case divide_by_code: { halfword amount = tex_scan_int(0, NULL); switch (level) { case int_val_level: case attr_val_level: case dimen_val_level: - value = tex_x_over_n(eq_value(index), amount); + value = tex_x_over_n(original, amount); break; case glue_val_level: case mu_val_level: { - halfword s = eq_value(index); - halfword r = tex_new_glue_spec_node(s); - glue_amount(r) = tex_x_over_n(glue_amount(s), amount); - glue_stretch(r) = tex_x_over_n(glue_stretch(s), amount); - glue_shrink(r) = tex_x_over_n(glue_shrink(s), amount); - value = r; + halfword newvalue = tex_new_glue_spec_node(original); + glue_amount(newvalue) = tex_x_over_n(glue_amount(original), amount); + glue_stretch(newvalue) = tex_x_over_n(glue_stretch(original), amount); + glue_shrink(newvalue) = tex_x_over_n(glue_shrink(original), amount); + value = newvalue; break; } default: @@ -3760,11 +3819,31 @@ static void tex_aux_arithmic_register(int a, int code) } if (lmt_scanner_state.arithmic_error) { tex_aux_arithmic_overflow_error(level, value); + } else if (simple) { + tex_define(a, index, simple, value); } else { tex_aux_update_register(a, level, index, value, varcmd); } break; } + /* + case advance_by_plus_one_code: + case advance_by_minus_one_code: + { + switch (level) { + case int_val_level: + case attr_val_level: + original += code == advance_by_plus_one_code ? 1 : -1; + if (simple) { + tex_define(a, index, simple, original); + } else { + tex_aux_update_register(a, level, index, original, varcmd); + } + break; + } + break; + } + */ } } } @@ -4171,8 +4250,20 @@ static void tex_aux_set_box(int a) static void tex_aux_set_shorthand_def(int a, int force) { halfword code = cur_chr; + /* + switch (code) { + case integer_def_csname_code: + case dimension_def_csname_code: + cur_cs = tex_create_csname(); + break; + default: + tex_get_r_token(); + break; + } + */ tex_get_r_token(); if (force || tex_define_permitted(cur_cs, a)) { + /* can we optimize the dual define, like no need to destroy in second call */ halfword p = cur_cs; tex_define(a, p, relax_cmd, relax_code); tex_scan_optional_equals(); @@ -4180,92 +4271,94 @@ static void tex_aux_set_shorthand_def(int a, int force) case char_def_code: { halfword chr = tex_scan_char_number(0); /* maybe 1 */ - tex_define(a, p, char_given_cmd, chr); + tex_define_again(a, p, char_given_cmd, chr); break; } case math_char_def_code: { mathcodeval mval = tex_scan_mathchar(tex_mathcode); - tex_define(a, p, mathspec_cmd, tex_new_math_spec(mval, tex_mathcode)); + tex_define_again(a, p, mathspec_cmd, tex_new_math_spec(mval, tex_mathcode)); break; } case math_dchar_def_code: { mathdictval dval = tex_scan_mathdict(); mathcodeval mval = tex_scan_mathchar(umath_mathcode); - tex_define(a, p, mathspec_cmd, tex_new_math_dict_spec(dval, mval, umath_mathcode)); + tex_define_again(a, p, mathspec_cmd, tex_new_math_dict_spec(dval, mval, umath_mathcode)); break; } case math_xchar_def_code: { mathcodeval mval = tex_scan_mathchar(umath_mathcode); - tex_define(a, p, mathspec_cmd, tex_new_math_spec(mval, umath_mathcode)); + tex_define_again(a, p, mathspec_cmd, tex_new_math_spec(mval, umath_mathcode)); break; } case count_def_code: { halfword n = tex_scan_int_register_number(); - tex_define(a, p, register_int_cmd, register_int_location(n)); + tex_define_again(a, p, register_int_cmd, register_int_location(n)); break; } case attribute_def_code: { halfword n = tex_scan_attribute_register_number(); - tex_define(a, p, register_attribute_cmd, register_attribute_location(n)); + tex_define_again(a, p, register_attribute_cmd, register_attribute_location(n)); break; } case dimen_def_code: { scaled n = tex_scan_dimen_register_number(); - tex_define(a, p, register_dimen_cmd, register_dimen_location(n)); + tex_define_again(a, p, register_dimen_cmd, register_dimen_location(n)); break; } case skip_def_code: { halfword n = tex_scan_glue_register_number(); - tex_define(a, p, register_glue_cmd, register_glue_location(n)); + tex_define_again(a, p, register_glue_cmd, register_glue_location(n)); break; } case mu_skip_def_code: { halfword n = tex_scan_mu_glue_register_number(); - tex_define(a, p, register_mu_glue_cmd, register_mu_glue_location(n)); + tex_define_again(a, p, register_mu_glue_cmd, register_mu_glue_location(n)); break; } case toks_def_code: { halfword n = tex_scan_toks_register_number(); - tex_define(a, p, register_toks_cmd, register_toks_location(n)); + tex_define_again(a, p, register_toks_cmd, register_toks_location(n)); break; } case lua_def_code: { halfword v = tex_scan_function_reference(1); - tex_define(a, p, is_protected(a) ? lua_protected_call_cmd : lua_call_cmd, v); + tex_define_again(a, p, is_protected(a) ? lua_protected_call_cmd : lua_call_cmd, v); } break; case integer_def_code: + /* case integer_def_csname_code: */ { halfword v = tex_scan_int(1, NULL); - tex_define(a, p, integer_cmd, v); + tex_define_again(a, p, integer_cmd, v); } break; case dimension_def_code: + /* case dimension_def_csname_code: */ { scaled v = tex_scan_dimen(0, 0, 0, 1, NULL); - tex_define(a, p, dimension_cmd, v); + tex_define_again(a, p, dimension_cmd, v); } break; case gluespec_def_code: { halfword v = tex_scan_glue(glue_val_level, 1); - tex_define(a, p, gluespec_cmd, v); + tex_define_again(a, p, gluespec_cmd, v); } break; case mugluespec_def_code: { halfword v = tex_scan_glue(mu_val_level, 1); - tex_define(a, p, mugluespec_cmd, v); + tex_define_again(a, p, mugluespec_cmd, v); } break; /* @@ -4677,13 +4770,13 @@ static void tex_aux_set_let(int a, int force) a = add_global_flag(a); } if (force || tex_define_permitted(cur_cs, a)) { - /*tex - The commented line permits plenty empty definitions, a |\let| can run out of - ref count so maybe some day \unknown - */ + // /*tex + // The commented line permits plenty empty definitions, a |\let| can run out of + // ref count so maybe some day \unknown + // */ // halfword empty = get_reference_token(); - halfword empty = lmt_token_state.empty; // tex_add_token_reference(empty); + halfword empty = lmt_token_state.empty; tex_define(a, cur_cs, tex_flags_to_cmd(a), empty); } return; @@ -4704,6 +4797,10 @@ static void tex_aux_set_let(int a, int force) singleword newf = 0; singleword cmd = (singleword) cur_cmd; if (is_aliased(a)) { + /*tex + Aliases only work for non constants: else make a |\def| of it or we need some + pointer to the original but as the meaning can change. Too tricky. + */ newf = oldf; } else { oldf = remove_overload_flags(oldf); @@ -5393,6 +5490,36 @@ static int tex_aux_set_some_item(halfword a) } } +static void tex_aux_set_constant_register(halfword cmd, halfword cs, halfword flags) +{ + switch(cmd) { + case integer_cmd: + { + halfword v = tex_scan_int(1, NULL); + tex_define(flags, cs, integer_cmd, v); + } + break; + case dimension_cmd: + { + scaled v = tex_scan_dimen(0, 0, 0, 1, NULL); + tex_define(flags, cs, dimension_cmd, v); + } + break; + case gluespec_cmd: + { + halfword v = tex_scan_glue(glue_val_level, 1); + tex_define(flags, cs, gluespec_cmd, v); + } + break; + case mugluespec_cmd: + { + halfword v = tex_scan_glue(mu_val_level, 1); + tex_define(flags, cs, mugluespec_cmd, v); + } + break; + } +} + void tex_run_prefixed_command(void) { /*tex accumulated prefix codes so far */ @@ -5550,6 +5677,12 @@ void tex_run_prefixed_command(void) tex_aux_run_illegal_case(); } break; + case integer_cmd: + case dimension_cmd: + case gluespec_cmd: + case mugluespec_cmd: + tex_aux_set_constant_register(cur_cmd, cur_cs, flags); + break; default: if (lastprefix < 0) { tex_confusion("prefixed command"); @@ -6340,11 +6473,10 @@ inline static void tex_aux_big_switch(int mode, int cmd) register_simple(set_specification_cmd, tex_run_prefixed_command); register_simple(shorthand_def_cmd, tex_run_prefixed_command); register_simple(lua_value_cmd, tex_run_prefixed_command); - - register_simple(integer_cmd, tex_aux_run_illegal_case); /*tex This is better than |run_relax|. */ - register_simple(dimension_cmd, tex_aux_run_illegal_case); /*tex This is better than |run_relax|. */ - register_simple(gluespec_cmd, tex_aux_run_illegal_case); /*tex This is better than |run_relax|. */ - register_simple(mugluespec_cmd, tex_aux_run_illegal_case); /*tex This is better than |run_relax|. */ + register_simple(integer_cmd, tex_run_prefixed_command); + register_simple(dimension_cmd, tex_run_prefixed_command); + register_simple(gluespec_cmd, tex_run_prefixed_command); + register_simple(mugluespec_cmd, tex_run_prefixed_command); register_simple(fontspec_cmd, tex_run_font_spec); diff --git a/source/luametatex/source/tex/texmath.c b/source/luametatex/source/tex/texmath.c index 216ba553b..ffc73cd12 100644 --- a/source/luametatex/source/tex/texmath.c +++ b/source/luametatex/source/tex/texmath.c @@ -3756,7 +3756,8 @@ static void tex_aux_flatten_math_list(halfword parent) switch (node_type(p)) { case simple_noad: { - if (! noad_has_following_scripts(p) && tex_math_has_class_option(node_subtype(p), flatten_class_option)) { + // how about the options and class + if (! noad_has_following_scripts(p) && tex_math_has_class_option(node_subtype(p), flatten_class_option) && ! noad_source(p)) { halfword n = noad_nucleus(p); halfword s = parent; node_type(s) = node_type(n); diff --git a/source/luametatex/source/tex/texnodes.c b/source/luametatex/source/tex/texnodes.c index a0601e594..f6daab056 100644 --- a/source/luametatex/source/tex/texnodes.c +++ b/source/luametatex/source/tex/texnodes.c @@ -1770,6 +1770,8 @@ int tex_n_of_used_nodes(int counts[]) return n; } +/* needs checking as we take from the pool */ + halfword tex_list_node_mem_usage(void) { char *saved_varmem_sizes = aux_allocate_array(sizeof(char), lmt_node_memory_state.nodes_data.allocated, 1); diff --git a/source/luametatex/source/tex/texnodes.h b/source/luametatex/source/tex/texnodes.h index 45e53187a..9cc1cbb39 100644 --- a/source/luametatex/source/tex/texnodes.h +++ b/source/luametatex/source/tex/texnodes.h @@ -898,18 +898,19 @@ typedef enum package_states { hbox_package_state = 0x01, vbox_package_state = 0x02, vtop_package_state = 0x03, + dbox_package_state = 0x04, /* maybe vcenter */ } package_states; typedef enum package_dimension_states { package_dimension_not_set = 0x00, - package_dimension_size_set = 0x04, + package_dimension_size_set = 0x10, } package_dimension_states; typedef enum package_leader_states { package_u_leader_not_set = 0x00, - package_u_leader_set = 0x08, - package_u_leader_delayed = 0x10, + package_u_leader_set = 0x20, + package_u_leader_delayed = 0x40, } package_leader_states; # define set_box_package_state(p,s) box_package_state(p) |= s diff --git a/source/luametatex/source/tex/texpackaging.c b/source/luametatex/source/tex/texpackaging.c index 796c3c1b7..9b7ff31bf 100644 --- a/source/luametatex/source/tex/texpackaging.c +++ b/source/luametatex/source/tex/texpackaging.c @@ -2335,7 +2335,7 @@ void tex_finish_vcenter_group(void) if (! tex_wrapped_up_paragraph(vcenter_par_context)) { halfword p; tex_end_paragraph(vcenter_group, vcenter_par_context); - tex_package(vpack_code); + tex_package(vbox_code); /* todo: vcenter_code */ p = tex_pop_tail(); if (p) { switch (node_type(p)) { @@ -2381,6 +2381,21 @@ inline static scaled tex_aux_checked_dimen2(halfword v) } } +static scaled tex_aux_first_height(halfword boxnode) +{ + halfword list = box_list(boxnode); + if (list) { + switch (node_type(list)) { + case hlist_node: + case vlist_node: + return box_height(list); + case rule_node: + return rule_height(list); + } + } + return 0; +} + void tex_package(singleword nature) { halfword context, spec, dirptr, attrlist, justpack, orientation, anchor, geometry, source, target, axis, mainclass, state, retain; @@ -2416,32 +2431,28 @@ void tex_package(singleword nature) } else { boxnode = tex_filtered_vpack(node_next(cur_list.head), spec, saved_level(saved_full_spec_item_packaging), maxdepth, grp, saved_level(saved_full_spec_item_direction), justpack, attrlist, state, retain); - if (nature == vtop_code) { - /*tex + switch (nature) { + case vtop_code: + { + /*tex - Read just the height and depth of |boxnode| (|boxnode|), for |\vtop|. The height of - a |\vtop| box is inherited from the first item on its list, if that item is an - |hlist_node|, |vlist_node|, or |rule_node|; otherwise the |\vtop| height is zero. + Read just the height and depth of |boxnode| (|boxnode|), for |\vtop|. The height of + a |\vtop| box is inherited from the first item on its list, if that item is an + |hlist_node|, |vlist_node|, or |rule_node|; otherwise the |\vtop| height is zero. - */ - scaled height = 0; - halfword list = box_list(boxnode); - if (list) { - switch (node_type(list)) { - case hlist_node: - case vlist_node: - height = box_height(list); - break; - case rule_node: - height = rule_height(list); - break; + */ + scaled height = tex_aux_first_height(boxnode); + box_depth(boxnode) = box_total(boxnode) - height; + box_height(boxnode) = height; + box_package_state(boxnode) = vtop_package_state; } - } - box_depth(boxnode) = box_total(boxnode) - height; - box_height(boxnode) = height; - box_package_state(boxnode) = vtop_package_state; - } else { - box_package_state(boxnode) = vbox_package_state; + break; + case vbox_code: + box_package_state(boxnode) = vbox_package_state; + break; + case dbox_code: + box_package_state(boxnode) = dbox_package_state; + break; } } if (dirptr) { @@ -2779,8 +2790,10 @@ inline static halfword tex_aux_depth_correction(halfword b, const line_break_pro { /*tex The deficiency of space between baselines: */ halfword p; + halfword height = has_box_package_state(b, dbox_package_state) ? tex_aux_first_height(b) : box_height(b); + halfword depth = cur_list.prev_depth; if (properties) { - scaled d = glue_amount(properties->baseline_skip) - cur_list.prev_depth - box_height(b); + scaled d = glue_amount(properties->baseline_skip) - depth - height; if (d < properties->line_skip_limit) { p = tex_new_glue_node(properties->line_skip, line_skip_glue); } else { @@ -2788,7 +2801,7 @@ inline static halfword tex_aux_depth_correction(halfword b, const line_break_pro glue_amount(p) = d; } } else { - scaled d = glue_amount(baseline_skip_par) - cur_list.prev_depth - box_height(b); + scaled d = glue_amount(baseline_skip_par) - depth - height; if (d < line_skip_limit_par) { p = tex_new_param_glue_node(line_skip_code, line_skip_glue); } else { @@ -3234,12 +3247,12 @@ void tex_begin_box(int boxcontext, scaled shift) boxnode = tex_copy_node(box_register(n)); break; } - case last_box_code: + /* case unpack_code: */ + /* break; */ + case last_box_code: /*tex - If the current list ends with a box node, delete it from the list and make |boxnode| point to it; otherwise set |boxnode := null|. - */ boxnode = null; if (abs(cur_list.mode) == mmode) { @@ -3276,11 +3289,8 @@ void tex_begin_box(int boxcontext, scaled shift) case vsplit_code: { /*tex - Split off part of a vertical box, make |boxnode| point to it. Here we deal with - things like |\vsplit 13 to 100pt|. - - Maybe todo: just split off one line. + things like |\vsplit 13 to 100pt|. Maybe todo: just split off one line. */ halfword mode = packing_exactly ; @@ -3342,15 +3352,23 @@ void tex_begin_box(int boxcontext, scaled shift) boxnode = tex_get_local_boxes(local_middle_box_code); break; } - default: - { - /*tex + /*tex - Initiate the construction of an hbox or vbox, then |return|. Here is where we - enter restricted horizontal mode or internal vertical mode, in order to make a - box. + Initiate the construction of an hbox or vbox, then |return|. Here is where we + enter restricted horizontal mode or internal vertical mode, in order to make a + box. The juggling with codes and addition or subtraction was somewhat messy. - */ + */ + /* case tpack_code: */ + /* case vpack_code: */ + /* case hpack_code: */ + /* case dpack_code: */ + /* case vtop_code: */ + /* case vbox_code: */ + /* case hbox_code: */ + /* case dbox_code: */ + default: + { int just_pack = 0; quarterword spec_direction = direction_unknown; /*tex 0 or |vmode| or |hmode| */ @@ -3368,6 +3386,10 @@ void tex_begin_box(int boxcontext, scaled shift) code = vtop_code + hmode; just_pack = 1; break; + case dpack_code: + code = dbox_code + hmode; + just_pack = 1; + break; } mode = code - vtop_code; tex_set_saved_record(saved_full_spec_item_context, box_context_save_type, 0, boxcontext); @@ -3392,7 +3414,7 @@ void tex_begin_box(int boxcontext, scaled shift) if (mode == vmode) { tex_aux_scan_full_spec(vbox_group, spec_direction, just_pack, shift); } else { - tex_aux_scan_full_spec(vtop_group, spec_direction, just_pack, shift); + tex_aux_scan_full_spec((code == dbox_code || code == dpack_code) ? dbox_group : vtop_group, spec_direction, just_pack, shift); mode = vmode; } tex_normal_paragraph(vmode_par_context); diff --git a/source/luametatex/source/tex/texpackaging.h b/source/luametatex/source/tex/texpackaging.h index b96d31353..5fd4bf9e4 100644 --- a/source/luametatex/source/tex/texpackaging.h +++ b/source/luametatex/source/tex/texpackaging.h @@ -27,9 +27,11 @@ typedef enum box_codes { tpack_code, vpack_code, hpack_code, + dpack_code, vtop_code, /*tex |chr_code| for |\vtop| */ vbox_code, hbox_code, + dbox_code, insert_box_code, insert_copy_code, local_left_box_box_code, diff --git a/source/luametatex/source/tex/texscanning.c b/source/luametatex/source/tex/texscanning.c index e4354bba1..a78a68a23 100644 --- a/source/luametatex/source/tex/texscanning.c +++ b/source/luametatex/source/tex/texscanning.c @@ -3111,8 +3111,6 @@ strnumber tex_the_scanned_result(void) push_selector; switch (cur_val_level) { case int_val_level: - tex_print_int(cur_val); - break; case attr_val_level: tex_print_int(cur_val); break; @@ -4134,7 +4132,7 @@ int tex_fract(int x, int n, int d, int max_answer) /*tex The main stacking logic approach is kept but I get the impression that the code is still - suboptimal. + suboptimal. We also accept braced expressions. */ @@ -4159,6 +4157,7 @@ static void tex_aux_scan_expr(halfword level) int error_b = 0; /*tex top of expression stack */ halfword top = null; +int braced = 0; /*tex Scan and evaluate an expression |e| of type |l|. */ cur_val_level = level; /* for now */ lmt_scanner_state.expression_depth++; @@ -4174,14 +4173,21 @@ static void tex_aux_scan_expr(halfword level) CONTINUE: operation = state == expression_none ? level : int_val_level; /* we abuse operation */ /*tex - Scan a factor |f| of type |o| or start a subexpression. Get the next non-blank non-call token. - */ + AGAIN: do { tex_get_x_token(); } while (cur_cmd == spacer_cmd); + if (! braced) { + if (cur_cmd == left_brace_cmd) { + braced = 1; + goto AGAIN; + } else { + braced = 2; + } + } if (cur_tok == left_parent_token) { /*tex Push the expression stack and |goto restart|. */ halfword t = tex_get_node(expression_node_size); @@ -4248,6 +4254,9 @@ static void tex_aux_scan_expr(halfword level) operation = expression_none; if (! top) { if (cur_cmd != relax_cmd) { + if (cur_cmd == right_brace_cmd && braced == 1) { + break; + } tex_back_input(cur_tok); } } else if (cur_tok != right_parent_token) { @@ -5085,10 +5094,11 @@ static void tex_aux_scan_expression(int level) stack_info stack = tex_aux_new_stack(); halfword operation = bit_expression_none; int alreadygotten = 0; + int braced = 0; int trace = tracing_expressions_par; while (1) { if (alreadygotten) { - alreadygotten= 0; + alreadygotten = 0; } else { tex_get_x_token(); } @@ -5096,6 +5106,21 @@ static void tex_aux_scan_expression(int level) switch (cur_cmd) { case relax_cmd: goto COLLECTED; + case left_brace_cmd: + if (! braced) { + braced = 1; + continue; + } else { + goto NUMBER; + // goto UNEXPECTED; + } + case right_brace_cmd: + if (braced) { + goto COLLECTED; + } else { + goto NUMBER; + // goto UNEXPECTED; + } case spacer_cmd: continue; case superscript_cmd: diff --git a/source/luametatex/source/tex/textoken.c b/source/luametatex/source/tex/textoken.c index f820e51d7..7a30b97eb 100644 --- a/source/luametatex/source/tex/textoken.c +++ b/source/luametatex/source/tex/textoken.c @@ -3359,6 +3359,8 @@ char *tex_tokenlist_to_tstring(int pp, int inhibit_par, int *siz, int skippreamb */ +/* The bin gets 1.2K smaller if we inline these. */ + halfword tex_get_tex_dimen_register (int j, int internal) { return internal ? dimen_parameter(j) : dimen_register(j) ; } halfword tex_get_tex_skip_register (int j, int internal) { return internal ? glue_parameter(j) : skip_register(j) ; } halfword tex_get_tex_mu_skip_register (int j, int internal) { return internal ? mu_glue_parameter(j) : mu_skip_register(j); } diff --git a/source/luametatex/source/tex/textypes.h b/source/luametatex/source/tex/textypes.h index c2cd57e64..0fa80dd99 100644 --- a/source/luametatex/source/tex/textypes.h +++ b/source/luametatex/source/tex/textypes.h @@ -208,6 +208,7 @@ extern halfword tex_badness( # define default_output_box 255 /*tex + For practical reasons all these registers were max'd to 64K but that really makes no sense for e.g. glue and mu glue and even attributes. Imagine using more than 8K attributes: we get long linked lists, slow lookup, lots of copying, need plenty node memory. These large ranges also @@ -225,31 +226,29 @@ extern halfword tex_badness( use less than in \LUATEX\ because we got rid of some parallel array so there it would have more impact). + At some point we might actually drop these maxima indeed as we really don't need that many + if these registers and if (say) 16K is not enough, then nothing is. + */ # if 1 - # define max_toks_register_index 0xFFFF /* 0xFFFF 0xFFFF 0x7FFF */ /* 64 64 32 */ # define max_box_register_index 0xFFFF /* 0xFFFF 0xFFFF 0x7FFF */ /* 64 64 32 */ - # define max_int_register_index 0xFFFF /* 0xFFFF 0xFFFF 0x7FFF */ /* 64 64 32 */ - # define max_dimen_register_index 0xFFFF /* 0xFFFF 0xFFFF 0x7FFF */ /* 64 64 32 */ + # define max_int_register_index 0xFFFF /* 0xFFFF 0xFFFF 0x3FFF */ /* 64 64 16 */ + # define max_dimen_register_index 0xFFFF /* 0xFFFF 0xFFFF 0x3FFF */ /* 64 64 16 */ # define max_attribute_register_index 0xFFFF /* 0xFFFF 0x7FFF 0x1FFF */ /* 64 32 8 */ - # define max_glue_register_index 0xFFFF /* 0xFFFF 0x7FFF 0x3FFF */ /* 64 32 8 */ + # define max_glue_register_index 0xFFFF /* 0xFFFF 0x7FFF 0x1FFF */ /* 64 32 8 */ # define max_mu_glue_register_index 0xFFFF /* 0xFFFF 0x3FFF 0x1FFF */ /* 64 16 8 */ - # define max_em_glue_register_index 0xFFFF /* 0xFFFF 0x3FFF 0x1FFF */ /* 64 16 8 */ - # define max_ex_glue_register_index 0xFFFF /* 0xFFFF 0x3FFF 0x1FFF */ /* 64 16 8 */ # else - # define max_toks_register_index 0x7FFF + # define max_toks_register_index 0x3FFF # define max_box_register_index 0x7FFF - # define max_int_register_index 0x7FFF - # define max_dimen_register_index 0x7FFF + # define max_int_register_index 0x1FFF + # define max_dimen_register_index 0x1FFF # define max_attribute_register_index 0x1FFF - # define max_glue_register_index 0x3FFF + # define max_glue_register_index 0x1FFF # define max_mu_glue_register_index 0x1FFF - # define max_em_glue_register_index 0x1FFF - # define max_ex_glue_register_index 0x1FFF # endif @@ -260,8 +259,6 @@ extern halfword tex_badness( # define max_n_of_attribute_registers (max_attribute_register_index + 1) # define max_n_of_glue_registers (max_glue_register_index + 1) # define max_n_of_mu_glue_registers (max_mu_glue_register_index + 1) -# define max_n_of_em_glue_registers (max_em_glue_register_index + 1) -# define max_n_of_ex_glue_registers (max_ex_glue_register_index + 1) # define max_n_of_bytecodes 65536 /* dynamic */ # define max_n_of_math_families 64 -- cgit v1.2.3