3 Copyright 2006-2012 Taco Hoekwater <taco@luatex.org>
5 This file is part of LuaTeX.
7 LuaTeX is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2 of the License, or (at your
10 option) any later version.
12 LuaTeX is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 License for more details.
17 You should have received a copy of the GNU General Public License along
18 with LuaTeX; if not, see <http://www.gnu.org/licenses/>. */
22 This module is unfinished and an intermediate step to removal of the old
23 token lib. Between version 0.80 and 0.85 the transition will be complete
24 and at the same time the input (buffer) handling will be cleaned up and
25 simplified. At that moment we can feed back tokens into the input.
27 The code can be optimized a bit by faster key checking. The scan functions
28 implemented here will stay functionally the same but can be improved if
29 needed. The old triplet model will disappear.
34 #include "lua/luatex-api.h"
36 typedef struct lua_token
{
41 typedef struct saved_tex_scanner
{
44 int save_cmd
, save_chr
, save_cs
, save_tok
;
47 #define save_tex_scanner(a) do { \
48 a.save_cmd = cur_cmd; \
49 a.save_chr = cur_chr; \
51 a.save_tok = cur_tok; \
54 #define unsave_tex_scanner(a) do { \
55 cur_cmd = a.save_cmd; \
56 cur_chr = a.save_chr; \
58 cur_tok = a.save_tok; \
61 #define TEX_ORIGIN 0 /* not used yet */
64 static lua_token
*check_istoken(lua_State
* L
, int ud
);
66 #define TOKEN_METATABLE "luatex_token"
69 #define DEBUG_OUT stdout
71 #define DEFAULT_SCAN_CODE_SET 2048 + 4096 /* default: letter and other */
73 /* two core helpers */
75 #define is_active_string(s) (strlen((char *)s)>3 && *s==0xEF && *(s+1)==0xBF && *(s+2)==0xBF)
77 void make_token_table(lua_State
* L
, int cmd
, int chr
, int cs
)
79 lua_createtable(L
, 3, 0);
80 lua_pushinteger(L
, cmd
);
81 lua_rawseti(L
, -2, 1);
82 lua_pushinteger(L
, chr
);
83 lua_rawseti(L
, -2, 2);
84 lua_pushinteger(L
, cs
);
85 lua_rawseti(L
, -2, 3);
88 static unsigned char *get_cs_text(int cs
)
91 return (unsigned char *) xstrdup("\\csname\\endcsname");
92 else if ((cs_text(cs
) < 0) || (cs_text(cs
) >= str_ptr
))
93 return (unsigned char *) xstrdup("");
95 return (unsigned char *) makecstring(cs_text(cs
));
98 /* maybe this qualify as a macro, not function */
100 static lua_token
*maybe_istoken(lua_State
* L
, int ud
)
102 lua_token
*p
= lua_touserdata(L
, ud
);
104 if (lua_getmetatable(L
, ud
)) {
105 lua_get_metatablelua(luatex_token
);
106 if (!lua_rawequal(L
, -1, -2))
114 /* we could make the message a function and just inline the rest (via a macro) */
116 lua_token
*check_istoken(lua_State
* L
, int ud
)
118 lua_token
*p
= maybe_istoken(L
, ud
);
121 formatted_error("token lib","lua <token> expected, not an object with type %s", luaL_typename(L
, ud
));
125 /* token library functions */
127 static void make_new_token(lua_State
* L
, int cmd
, int chr
, int cs
)
130 lua_token
*thetok
= lua_newuserdata(L
, sizeof(lua_token
));
131 thetok
->origin
= LUA_ORIGIN
;
132 fast_get_avail(thetok
->token
);
133 tok
= (cs
? cs_token_flag
+ cs
: token_val(cmd
, chr
));
134 set_token_info(thetok
->token
, tok
);
135 lua_get_metatablelua(luatex_token
);
136 lua_setmetatable(L
, -2);
139 static void push_token(lua_State
* L
, int tok
)
141 lua_token
*thetok
= lua_newuserdata(L
, sizeof(lua_token
));
142 thetok
->origin
= LUA_ORIGIN
;
144 lua_get_metatablelua(luatex_token
);
145 lua_setmetatable(L
, -2);
148 /* static int run_get_cs_offset(lua_State * L) */
150 /* lua_pushinteger(L, cs_token_flag); */
154 /* static int run_get_command_id(lua_State * L) */
157 /* if (lua_type(L, -1) == LUA_TSTRING) { */
158 /* cs = get_command_id(lua_tostring(L, -1)); */
160 /* lua_pushinteger(L, cs); */
164 /* static int run_get_csname_id(lua_State * L) */
167 /* size_t k, cs = 0; */
168 /* if (lua_type(L, -1) == LUA_TSTRING) { */
169 /* s = lua_tolstring(L, -1, &k); */
170 /* cs = (size_t) string_lookup(s, k); */
172 /* lua_pushinteger(L, (lua_Number) cs); */
176 static int run_get_next(lua_State
* L
)
178 saved_tex_scanner texstate
;
179 save_tex_scanner(texstate
);
181 make_new_token(L
, cur_cmd
, cur_chr
, cur_cs
);
182 unsave_tex_scanner(texstate
);
187 This is experimental code:
189 local t1 = token.get_next()
190 local t2 = token.get_next()
191 local t3 = token.get_next()
192 local t4 = token.get_next()
193 -- watch out, we flush in sequence
194 token.put_next { t1, t2 }
195 -- but this one gets pushed in front
196 token.put_next ( t3, t4 )
197 -- so when we get wxyz we put yzwx!
199 At some point we can consider a token.print that delays and goes via
200 the same rope mechanism as texio.prints and friends but then one can
201 as well serialize the tokens and do a normal print so there is no real
202 gain in it. After all, the tokenlib operates at the input level so we
203 might as well keep it there.
207 inline static int run_put_next(lua_State
* L
)
209 int n
= lua_gettop(L
);
217 /* we accept a single nil argument */
220 lua_get_metatablelua(luatex_token
);
222 if (lua_type(L
,1) == LUA_TTABLE
) {
224 normal_error("token lib","only one table permitted in put_next");
227 lua_rawgeti(L
, 1, i
); /* table mt token */
228 if (lua_type(L
,-1) == LUA_TNIL
) {
231 p
= lua_touserdata(L
, -1);
233 normal_error("token lib","lua <token> expected in put_next (1)");
234 } else if (!lua_getmetatable(L
, -1)) { /* table mt token mt */
235 normal_error("token lib","lua <token> expected in put_next (2)");
236 } else if (!lua_rawequal(L
, m
, -1)) {
237 normal_error("token lib","lua <token> expected in put_next (3)");
240 token_info(x
) = token_info(p
->token
);
253 for (i
= 1; i
<= n
; i
++) {
254 p
= lua_touserdata(L
,i
);
256 normal_error("token lib","lua <token> expected in put_next (4)");
257 } else if (!lua_getmetatable(L
, i
)) { /* table mt token mt */
258 normal_error("token lib","lua <token> expected in put_next (5)");
259 } else if (!lua_rawequal(L
, m
, -1)) {
260 normal_error("token lib","lua <token> expected in put_next (6)");
263 token_info(x
) = token_info(p
->token
);
277 begin_token_list(h
,0);
283 static int run_scan_keyword(lua_State
* L
)
285 saved_tex_scanner texstate
;
286 const char *s
= luaL_checkstring(L
, -1);
289 save_tex_scanner(texstate
);
290 if (scan_keyword(s
)) {
293 unsave_tex_scanner(texstate
);
295 lua_pushboolean(L
,v
);
299 static int run_scan_csname(lua_State
* L
)
303 saved_tex_scanner texstate
;
304 save_tex_scanner(texstate
);
306 t
= (cur_cs
? cs_token_flag
+ cur_cs
: token_val(cur_cmd
, cur_chr
));
307 if (t
>= cs_token_flag
&& ((s
= get_cs_text(t
- cs_token_flag
)) != (unsigned char *) NULL
)) {
308 if (is_active_string(s
))
309 lua_pushstring(L
, (char *) (s
+ 3));
311 lua_pushstring(L
, (char *) s
);
315 unsave_tex_scanner(texstate
);
319 static int run_scan_int(lua_State
* L
)
321 saved_tex_scanner texstate
;
323 save_tex_scanner(texstate
);
326 unsave_tex_scanner(texstate
);
327 lua_pushinteger(L
,(int)v
);
331 static int run_scan_dimen(lua_State
* L
)
333 saved_tex_scanner texstate
;
335 int inf
= false, mu
= false;
336 int t
= lua_gettop(L
);
338 inf
= lua_toboolean(L
,1); /* inf values allowed ?*/
340 mu
= lua_toboolean(L
,2); /* mu units required ?*/
341 save_tex_scanner(texstate
);
342 scan_dimen( mu
,inf
, false); /* arg3 = shortcut */
345 unsave_tex_scanner(texstate
);
346 lua_pushinteger(L
,v
);
348 lua_pushinteger(L
,(lua_Number
)o
);
355 static int run_scan_glue(lua_State
* L
)
357 saved_tex_scanner texstate
;
360 int t
= lua_gettop(L
);
362 mu
= lua_toboolean(L
,1); /* mu units required ?*/
363 save_tex_scanner(texstate
);
364 scan_glue((mu
? mu_val_level
: glue_val_level
));
365 v
= cur_val
; /* which is a glue_spec node */
366 unsave_tex_scanner(texstate
);
367 lua_nodelib_push_fast(L
,(halfword
)v
);
371 static int run_scan_toks(lua_State
* L
)
373 saved_tex_scanner texstate
;
374 int macro_def
= false, xpand
= false;
375 halfword t
, saved_defref
;
377 int top
= lua_gettop(L
);
379 macro_def
= lua_toboolean(L
,1); /* \\def ? */
381 xpand
= lua_toboolean(L
,2); /* expand ? */
382 save_tex_scanner(texstate
);
383 saved_defref
= def_ref
;
384 (void) scan_toks(macro_def
, xpand
);
386 unsave_tex_scanner(texstate
);
387 def_ref
= saved_defref
;
388 /* This function returns a pointer to the tail of a new token
389 list, and it also makes |def_ref| point to the reference count at the
390 head of that list. */
392 while (token_link(t
)) {
395 lua_rawseti(L
,-2,i
++);
400 static int run_scan_string(lua_State
* L
) /* HH */
401 { /* can be simplified, no need for intermediate list */
402 saved_tex_scanner texstate
;
403 halfword t
, saved_defref
;
404 save_tex_scanner(texstate
);
407 } while ((cur_cmd
== spacer_cmd
) || (cur_cmd
== relax_cmd
));
408 if (cur_cmd
== left_brace_cmd
) {
410 saved_defref
= def_ref
;
411 (void) scan_toks(false, true);
413 def_ref
= saved_defref
;
414 tokenlist_to_luastring(L
,t
);
415 } else if (cur_cmd
== call_cmd
) {
416 t
= token_link(cur_chr
);
417 tokenlist_to_luastring(L
,t
);
419 if (cur_cmd
== 11 || cur_cmd
== 12 ) {
422 luaL_buffinit(L
,&b
) ;
424 str
= (char *) uni2str(cur_chr
);
425 luaL_addstring(&b
,(char *) str
);
427 if (cur_cmd
!= 11 && cur_cmd
!= 12 ) {
438 unsave_tex_scanner(texstate
);
442 static int run_scan_word(lua_State
* L
) /* HH */
444 saved_tex_scanner texstate
;
445 save_tex_scanner(texstate
);
448 } while ((cur_cmd
== spacer_cmd
) || (cur_cmd
== relax_cmd
));
449 if (cur_cmd
== 11 || cur_cmd
== 12 ) {
452 luaL_buffinit(L
,&b
) ;
454 str
= (char *) uni2str(cur_chr
);
455 luaL_addstring(&b
,str
);
458 if (cur_cmd
!= 11 && cur_cmd
!= 12 ) {
468 unsave_tex_scanner(texstate
);
472 static int run_scan_code(lua_State
* L
) /* HH */
474 saved_tex_scanner texstate
;
475 int cc
= DEFAULT_SCAN_CODE_SET
;
476 save_tex_scanner(texstate
);
479 if (lua_gettop(L
)>0) {
480 cc
= (int) lua_tointeger(L
,-1);
482 /* todo: message that we choose a default */
483 cc
= DEFAULT_SCAN_CODE_SET
;
486 if (cc
& (1<<(cur_cmd
))) {
487 lua_pushinteger(L
,(int)cur_chr
);
496 unsave_tex_scanner(texstate
);
500 static int lua_tokenlib_is_token(lua_State
* L
) /* HH */
502 lua_pushboolean(L
,maybe_istoken(L
,1)==NULL
? 0 : 1);
506 /* static int run_expand(lua_State * L) */
513 static int run_lookup(lua_State
* L
)
518 if (lua_type(L
, -1) == LUA_TSTRING
) {
519 s
= lua_tolstring(L
, -1, &l
);
521 cs
= string_lookup(s
, l
);
524 make_new_token(L
, cmd
, chr
, cs
);
532 static int run_build(lua_State
* L
)
534 if (lua_type(L
, 1) == LUA_TNUMBER
) {
536 int chr
= (int) lua_tointeger(L
, 1);
537 int cmd
= (int) luaL_optinteger(L
, 2, get_cat_code(int_par(cat_code_table_code
),chr
));
538 if (cmd
== 0 || cmd
== 9 || cmd
== 14 || cmd
== 15) {
539 formatted_warning("token lib","not a good token, catcode %i can not be returned, so 12 will be used",(int) cmd
);
541 } else if (cmd
== 13) {
542 cs
= active_to_cs(chr
, false);
546 make_new_token(L
, cmd
, chr
, cs
);
549 return run_lookup(L
);
553 /* token instance functions */
555 static int lua_tokenlib_free(lua_State
* L
)
558 n
= check_istoken(L
, 1);
559 if (n
->origin
== LUA_ORIGIN
) {
560 free_avail(n
->token
);
567 inline static int lua_tokenlib_get_command(lua_State
* L
)
569 lua_token
*n
= check_istoken(L
, 1);
570 halfword t
= token_info(n
->token
);
571 if (t
>= cs_token_flag
) {
572 lua_pushinteger(L
,(int) eq_type((t
- cs_token_flag
)));
574 lua_pushinteger(L
, token_cmd(t
));
579 inline static int lua_tokenlib_get_index(lua_State
* L
)
581 lua_token
*n
= check_istoken(L
, 1);
582 halfword t
= token_info(n
->token
);
583 int cmd
= (t
>= cs_token_flag
? eq_type(t
- cs_token_flag
) : token_cmd(t
));
584 halfword e
= equiv(t
- cs_token_flag
);
589 case assign_attr_cmd
:
592 case assign_dimen_cmd
:
595 case assign_glue_cmd
:
598 case assign_mu_glue_cmd
:
601 case assign_toks_cmd
:
608 if ((e
>= 0) && (e
<= 65535)) {
609 lua_pushinteger(L
, e
);
616 inline static int lua_tokenlib_get_mode(lua_State
* L
)
618 lua_token
*n
= check_istoken(L
, 1);
619 halfword t
= token_info(n
->token
);
620 if (t
>= cs_token_flag
) {
621 lua_pushinteger(L
, equiv(t
- cs_token_flag
));
623 lua_pushinteger(L
, token_chr(t
));
628 inline static int lua_tokenlib_get_cmdname(lua_State
* L
)
630 lua_token
*n
= check_istoken(L
, 1);
631 halfword t
= token_info(n
->token
);
632 int cmd
= (t
>= cs_token_flag
? eq_type(t
- cs_token_flag
) : token_cmd(t
));
633 lua_pushstring(L
, command_names
[cmd
].cmd_name
); /* can be sped up */
637 inline static int lua_tokenlib_get_csname(lua_State
* L
)
639 lua_token
*n
= check_istoken(L
, 1);
640 halfword t
= token_info(n
->token
);
642 if (t
>= cs_token_flag
&& ((s
= get_cs_text(t
- cs_token_flag
)) != (unsigned char *) NULL
)) {
643 if (is_active_string(s
))
644 lua_pushstring(L
, (char *) (s
+ 3));
646 lua_pushstring(L
, (char *) s
);
653 inline static int lua_tokenlib_get_id(lua_State
* L
)
655 lua_token
*n
= check_istoken(L
, 1);
656 lua_pushinteger(L
, n
->token
);
660 inline static int lua_tokenlib_get_tok(lua_State
* L
)
662 lua_token
*n
= check_istoken(L
, 1);
663 halfword t
= token_info(n
->token
);
664 lua_pushinteger(L
, t
);
668 inline static int lua_tokenlib_get_active(lua_State
* L
)
670 lua_token
*n
= check_istoken(L
, 1);
671 halfword t
= token_info(n
->token
);
673 if (t
>= cs_token_flag
&& ((s
= get_cs_text(t
- cs_token_flag
)) != (unsigned char *) NULL
)) {
674 if (is_active_string(s
))
675 lua_pushboolean(L
,1);
677 lua_pushboolean(L
,0);
680 lua_pushboolean(L
,0);
685 inline static int lua_tokenlib_get_expandable(lua_State
* L
)
687 lua_token
*n
= check_istoken(L
, 1);
688 halfword t
= token_info(n
->token
);
689 int cmd
= (t
>= cs_token_flag
? eq_type(t
- cs_token_flag
) : token_cmd(t
));
690 if (cmd
> max_command_cmd
) {
691 lua_pushboolean(L
, 1);
693 lua_pushboolean(L
, 0);
698 inline static int lua_tokenlib_get_protected(lua_State
* L
)
700 lua_token
*n
= check_istoken(L
, 1);
701 halfword t
= token_info(n
->token
);
702 int cmd
= (t
>= cs_token_flag
? eq_type(t
- cs_token_flag
) : token_cmd(t
));
703 if (cmd
> max_command_cmd
&& (cmd
>= call_cmd
) && (cmd
< end_template_cmd
)) {
704 int chr
= (t
>= cs_token_flag
? equiv(t
- cs_token_flag
) : token_chr(t
));
705 if (token_info(token_link(chr
)) == protected_token
) {
706 lua_pushboolean(L
, 1);
708 lua_pushboolean(L
, 0);
711 lua_pushboolean(L
, 0);
716 static int lua_tokenlib_getfield(lua_State
* L
)
718 const char *s
= lua_tostring(L
, 2);
719 if (lua_key_eq(s
, command
)) {
720 return lua_tokenlib_get_command(L
);
721 } else if (lua_key_eq(s
, index
)) {
722 return lua_tokenlib_get_index(L
);
723 } else if (lua_key_eq(s
, mode
)) {
724 return lua_tokenlib_get_mode(L
);
725 } else if (lua_key_eq(s
, cmdname
)) {
726 return lua_tokenlib_get_cmdname(L
);
727 } else if (lua_key_eq(s
, csname
)) {
728 return lua_tokenlib_get_csname(L
);
729 } else if (lua_key_eq(s
, id
)) {
730 return lua_tokenlib_get_id(L
);
731 } else if (lua_key_eq(s
, tok
)) {
732 return lua_tokenlib_get_tok(L
);
733 } else if (lua_key_eq(s
, active
)) {
734 return lua_tokenlib_get_active(L
);
735 } else if (lua_key_eq(s
, expandable
)) {
736 return lua_tokenlib_get_expandable(L
);
737 } else if (lua_key_eq(s
, protected)) {
738 return lua_tokenlib_get_protected(L
);
747 static int lua_tokenlib_equal(lua_State
* L
)
750 n
= check_istoken(L
, 1);
751 m
= check_istoken(L
, 2);
752 if (token_info(n
->token
) == token_info(m
->token
)) {
753 lua_pushboolean(L
,1);
756 lua_pushboolean(L
,0);
760 static int lua_tokenlib_tostring(lua_State
* L
)
764 n
= check_istoken(L
, 1);
766 snprintf(msg
, 255, "<%s token %d: %d>", (n
->origin
==LUA_ORIGIN
?"lua":"tex"), n
->token
, token_info(n
->token
));
767 lua_pushstring(L
, msg
);
772 static int lua_tokenlib_type(lua_State
* L
)
774 if (maybe_istoken(L
,1)!=NULL
) {
775 lua_pushstring(L
,"token");
782 static int run_scan_token(lua_State
* L
)
784 saved_tex_scanner texstate
;
785 save_tex_scanner(texstate
);
787 make_new_token(L
, cur_cmd
, cur_chr
, cur_cs
);
788 unsave_tex_scanner(texstate
);
794 /* [catcodetable] csname content : \def\csname{content} */
795 /* [catcodetable] csname content global : \gdef\csname{content} */
796 /* [catcodetable] csname : \def\csname{} */
798 /* TODO: check for a quick way to set a macro to empty (HH) */
800 static int set_macro(lua_State
* L
)
802 const char *name
= null
;
803 const char *str
= null
;
804 const char *s
= null
;
808 int n
= lua_gettop(L
);
809 int a
= 0 ; /* global state */
810 int nncs
= no_new_control_sequence
;
814 if (lua_type(L
, 1) == LUA_TNUMBER
) {
817 ct
= (int) lua_tointeger(L
, 1);
818 name
= lua_tolstring(L
, 2, &lname
);
820 str
= lua_tolstring(L
, 3, &lstr
);
822 s
= lua_tostring(L
, 4);
824 ct
= int_par(cat_code_table_code
) ;
825 name
= lua_tolstring(L
, 1, &lname
);
827 str
= lua_tolstring(L
, 2, &lstr
);
829 s
= lua_tostring(L
, 3);
834 if (s
&& (lua_key_eq(s
, global
))) {
837 no_new_control_sequence
= false ;
838 cs
= string_lookup(name
, lname
);
839 no_new_control_sequence
= nncs
;
841 halfword p
; /* tail of the token list */
842 halfword q
; /* new node being added to the token list via |store_new_token| */
843 halfword t
; /* token being appended */
844 const char *se
= str
+ lstr
;
846 set_token_link(p
, null
);
847 /* this left brace is used to store the number of arguments */
848 fast_store_new_token(left_brace_token
);
849 /* and this ends the not present arguments, and no: we will not support arguments here*/
850 fast_store_new_token(end_match_token
);
852 /* hh: str2uni could return len too (also elsewhere) */
853 t
= (halfword
) str2uni((const unsigned char *) str
);
855 cc
= get_cat_code(ct
,t
);
856 /* this is a relating simple converter; if more is needed one can just use */
857 /* tex.print with a regular \def or \gdef and feed the string into the regular */
860 /* we have a potential control sequence so we check for it */
864 halfword _cs
= null
;
865 const char *_name
= str
;
867 t
= (halfword
) str2uni((const unsigned char *) str
);
869 _c
= get_cat_code(ct
,t
);
872 _lname
= _lname
+ _s
;
873 } else if (_c
== 10) {
874 /* we ignore a trailing space like normal scanning does */
882 /* we have a potential \cs */
883 _cs
= string_lookup(_name
, _lname
);
884 if (_cs
== undefined_control_sequence
) {
885 /* let's play safe and backtrack */
886 t
= cc
* (1<<21) + t
;
889 t
= cs_token_flag
+ _cs
;
892 /* just a character with some meaning, so \unknown becomes effectively */
893 /* \\unknown assuming that \\ has some useful meaning of course */
894 t
= cc
* (1<<21) + t
;
899 /* whatever token, so for instance $x^2$ just works given a tex */
901 t
= cc
* (1<<21) + t
;
903 fast_store_new_token(t
);
905 /* there is no fast_store_new_token(right_brace_token) needed */
906 define(cs
, call_cmd
+ (a
% 4), token_link(temp_token_head
));
909 halfword q
; /* new node being added to the token list via |store_new_token| */
911 set_token_info(p
,null
);
912 fast_store_new_token(left_brace_token
);
913 fast_store_new_token(end_match_token
);
914 define(cs
, call_cmd
+ (a
% 4), token_link(temp_token_head
));
919 static const struct luaL_Reg tokenlib
[] = {
920 { "type", lua_tokenlib_type
},
921 { "create", run_build
},
922 { "is_token", lua_tokenlib_is_token
},
924 { "get_next", run_get_next
},
925 { "put_next", run_put_next
},
926 { "scan_keyword", run_scan_keyword
},
927 { "scan_int", run_scan_int
},
928 { "scan_dimen", run_scan_dimen
},
929 { "scan_glue", run_scan_glue
},
930 { "scan_toks", run_scan_toks
},
931 { "scan_code", run_scan_code
},
932 { "scan_string", run_scan_string
},
933 { "scan_word", run_scan_word
},
934 { "scan_csname", run_scan_csname
},
935 { "scan_token", run_scan_token
}, /* expands next token if needed */
936 /* push into input stream */
938 { "write",luatwrite },
941 { "get_command", lua_tokenlib_get_command
},
942 { "get_index", lua_tokenlib_get_index
},
943 { "get_mode", lua_tokenlib_get_mode
},
944 { "get_cmdname", lua_tokenlib_get_cmdname
},
945 { "get_csname", lua_tokenlib_get_csname
},
946 { "get_id", lua_tokenlib_get_id
},
947 { "get_tok", lua_tokenlib_get_tok
},
948 { "get_active", lua_tokenlib_get_active
},
949 { "get_expandable", lua_tokenlib_get_expandable
},
950 { "get_protected", lua_tokenlib_get_protected
},
951 /* maybe more setters */
952 { "set_macro", set_macro
},
954 /* {"expand", run_expand}, */ /* does not work yet! */
955 /* {"csname_id", run_get_csname_id}, */ /* yes or no */
956 /* {"command_id", run_get_command_id}, */ /* yes or no */
957 /* {"cs_offset", run_get_cs_offset}, */ /* not that useful */
961 static const struct luaL_Reg tokenlib_m
[] = {
962 {"__index", lua_tokenlib_getfield
},
963 {"__tostring", lua_tokenlib_tostring
},
964 {"__eq", lua_tokenlib_equal
},
965 {"__gc", lua_tokenlib_free
},
966 {NULL
, NULL
} /* sentinel */
969 int luaopen_token(lua_State
* L
)
971 /* the main metatable of token userdata */
972 luaL_newmetatable(L
, TOKEN_METATABLE
);
973 luaL_register(L
, NULL
, tokenlib_m
);
974 luaL_register(L
, "token", tokenlib
);