summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2023-01-29 21:21:33 +0000
committerKarl Berry <karl@freefriends.org>2023-01-29 21:21:33 +0000
commitefd04c4c2b49f26b1240861e3ce3d274d8014183 (patch)
tree9f7447393cdf5f0749585b928e233ae5486b5812 /Master/texmf-dist/tex
parent10f178a835cbfc131f2b6d046596b19871bb5e86 (diff)
piton (29jan23)
git-svn-id: svn://tug.org/texlive/trunk@65673 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex')
-rw-r--r--Master/texmf-dist/tex/lualatex/piton/piton.sty263
1 files changed, 186 insertions, 77 deletions
diff --git a/Master/texmf-dist/tex/lualatex/piton/piton.sty b/Master/texmf-dist/tex/lualatex/piton/piton.sty
index 3142a900c8e..c630fd80755 100644
--- a/Master/texmf-dist/tex/lualatex/piton/piton.sty
+++ b/Master/texmf-dist/tex/lualatex/piton/piton.sty
@@ -18,9 +18,8 @@
%% and version 1.3 or later is part of all distributions of
%% LaTeX version 2005/12/01 or later.
%%
-\def\myfileversion{1.2}
-\def\myfiledate{2023/01/16}
-
+\def\myfileversion{1.3}
+\def\myfiledate{2023/01/29}
\bigskip
@@ -136,7 +135,8 @@
\tl_new:N \g__piton_aux_tl
\int_new:N \l__piton_splittable_int
\int_set:Nn \l__piton_splittable_int { 100 }
-\str_new:N \l__piton_background_color_str
+\str_new:N \l__piton_bg_color_tl
+\str_new:N \l__piton_prompt_bg_color_tl
\dim_new:N \g__piton_width_dim
\dim_new:N \l__piton_width_on_aux_dim
\int_new:N \g__piton_env_int
@@ -172,6 +172,29 @@
\str_set:Nn \l__piton_beamer_command_str { #1 }
\use:c { #1 }
}
+\cs_new_protected:Npn \__piton_label:n #1
+ {
+ \bool_if:NTF \l__piton_line_numbers_bool
+ {
+ \@bsphack
+ \protected@write \@auxout { }
+ {
+ \string \newlabel { #1 }
+ {
+ { \int_eval:n { \g__piton_visual_line_int + 1 } }
+ { \thepage }
+ }
+ }
+ \@esphack
+ }
+ { \msg_error:nn { piton } { label~with~lines~numbers } }
+ }
+\tl_new:N \g__piton_begin_line_hook_tl
+\cs_new_protected:Npn \__piton_prompt:
+ {
+ \tl_gset:Nn \g__piton_begin_line_hook_tl
+ { \tl_set:NV \l__piton_bg_color_tl \l__piton_prompt_bg_color_tl }
+ }
\cs_new_protected:Npn \__piton_replace_spaces:n #1
{
\tl_set:Nn \l_tmpa_tl { #1 }
@@ -191,11 +214,13 @@
\cs_generate_variant:Nn \__piton_replace_spaces:n { x }
\cs_set_protected:Npn \__piton_begin_line: #1 \__piton_end_line:
{
+ \group_begin:
+ \g__piton_begin_line_hook_tl
\int_gzero:N \g__piton_indentation_int
\bool_if:NTF \l__piton_slim_bool
{ \hcoffin_set:Nn \l_tmpa_coffin }
{
- \str_if_empty:NTF \l__piton_background_color_str
+ \str_if_empty:NTF \l__piton_bg_color_tl
{
\vcoffin_set:Nnn \l_tmpa_coffin
{ \dim_eval:n { \linewidth - \l__piton_left_margin_dim } }
@@ -221,7 +246,7 @@
{ \tl_if_empty:nF { #1 } }
\__piton_print_number:
}
- \str_if_empty:NF \l__piton_background_color_str
+ \tl_if_empty:NF \l__piton_bg_color_tl
{ \skip_horizontal:n { 0.5 em } }
\coffin_typeset:Nnnnn \l_tmpa_coffin T l \c_zero_dim \c_zero_dim
}
@@ -229,14 +254,14 @@
{ \dim_gset:Nn \g__piton_width_dim { \box_wd:N \l_tmpa_box } }
\box_set_dp:Nn \l_tmpa_box { \box_dp:N \l_tmpa_box + 1.25 pt }
\box_set_ht:Nn \l_tmpa_box { \box_ht:N \l_tmpa_box + 1.25 pt }
- \tl_if_empty:NTF \l__piton_background_color_str
+ \str_if_empty:NTF \l__piton_bg_color_tl
{ \box_use_drop:N \l_tmpa_box }
{
\vbox_top:n
{
\hbox:n
{
- \exp_args:NV \color \l__piton_background_color_str
+ \__piton_color:V \l__piton_bg_color_tl
\vrule height \box_ht:N \l_tmpa_box
depth \box_dp:N \l_tmpa_box
width \l__piton_width_on_aux_dim
@@ -247,7 +272,20 @@
}
}
\vspace { - 2.5 pt }
+ \group_end:
+ \tl_gclear:N \g__piton_begin_line_hook_tl
}
+\cs_set_protected:Npn \__piton_color:n #1
+ {
+ \tl_if_head_eq_meaning:nNTF { #1 } [
+ {
+ \tl_set:Nn \l_tmpa_tl { #1 }
+ \tl_set_rescan:Nno \l_tmpa_tl { } \l_tmpa_tl
+ \exp_last_unbraced:NV \color \l_tmpa_tl
+ }
+ { \color { #1 } }
+ }
+\cs_generate_variant:Nn \__piton_color:n { V }
\cs_new_protected:Npn \__piton_newline:
{
\int_gincr:N \g__piton_line_int
@@ -276,7 +314,7 @@
\l__piton_continuation_symbol_tl
}
\skip_horizontal:n { 0.3 em }
- \str_if_empty:NF \l__piton_background_color_str
+ \tl_if_empty:NF \l__piton_bg_color_tl
{ \skip_horizontal:n { 0.5 em } }
}
\bool_if:NT \l__piton_indent_broken_lines_bool
@@ -313,8 +351,10 @@
resume .value_forbidden:n = true ,
splittable .int_set:N = \l__piton_splittable_int ,
splittable .default:n = 1 ,
- background-color .str_set:N = \l__piton_background_color_str ,
+ background-color .str_set:N = \l__piton_bg_color_tl ,
background-color .value_required:n = true ,
+ prompt-background-color .str_set:N = \l__piton_prompt_bg_color_tl ,
+ prompt-background-color .value_required:n = true ,
slim .bool_set:N = \l__piton_slim_bool ,
slim .default:n = true ,
left-margin .code:n =
@@ -348,36 +388,6 @@
unknown .code:n =
\msg_error:nn { piton } { Unknown~key~for~PitonOptions }
}
-\msg_new:nnnn { piton } { Unknown~key~for~PitonOptions }
- {
- Unknown~key. \\
- The~key~'\l_keys_key_str'~is~unknown~for~\token_to_str:N \PitonOptions.~
- It~will~be~ignored.\\
- For~a~list~of~the~available~keys,~type~H~<return>.
- }
- {
- The~available~keys~are~(in~alphabetic~order):~
- all-line-numbers,~
- auto-gobble,~
- break-lines,~
- break-lines-in-piton,~
- break-lines-in-Piton,~
- continuation-symbol,~
- continuation-symbol-on-indentation,~
- end-of-broken-line,~
- env-gobble,~
- gobble,~
- indent-broken-lines,~
- left-margin,~
- line-numbers,~
- resume,~
- show-spaces,~
- show-spaces-in-strings,~
- slim,~
- splittable,~
- tabs-auto-gobble,~
- and~tab-size.
- }
\NewDocumentCommand \PitonOptions { } { \keys_set:nn { PitonOptions } }
\int_new:N \g__piton_visual_line_int
\cs_new_protected:Npn \__piton_print_number:
@@ -407,7 +417,7 @@
{
\bool_if:NT \l__piton_slim_bool
{
- \str_if_empty:NF \l__piton_background_color_str
+ \tl_if_empty:NF \l__piton_bg_color_tl
{
\tl_gput_right:Nx \g__piton_aux_tl
{
@@ -423,15 +433,17 @@
{
\group_begin:
\ttfamily
+ \automatichyphenmode = 1
\cs_set_eq:NN \\ \c_backslash_str
\cs_set_eq:NN \% \c_percent_str
\cs_set_eq:NN \{ \c_left_brace_str
\cs_set_eq:NN \} \c_right_brace_str
\cs_set_eq:NN \$ \c_dollar_str
+ \cs_set_eq:cN { ~ } \space
\cs_set_protected:Npn \__piton_begin_line: { }
\cs_set_protected:Npn \__piton_end_line: { }
\tl_set:Nx \l_tmpa_tl
- { \lua_now:n { piton.pitonParse(token.scan_string()) } { #1 } }
+ { \lua_now:n { piton.ParseBis(token.scan_string()) } { #1 } }
\bool_if:NTF \l__piton_show_spaces_bool
{ \regex_replace_all:nnN { \x20 } { ␣ } \l_tmpa_tl } % U+2423
{
@@ -445,6 +457,7 @@
{
\group_begin:
\ttfamily
+ \automatichyphenmode = 1
\cs_set_protected:Npn \__piton_begin_line: { }
\cs_set_protected:Npn \__piton_end_line: { }
\tl_set:Nx \l_tmpa_tl
@@ -454,13 +467,23 @@
\l_tmpa_tl
\group_end:
}
+
\cs_new_protected:Npn \__piton_piton:n #1
{
\group_begin:
\cs_set_protected:Npn \__piton_begin_line: { }
\cs_set_protected:Npn \__piton_end_line: { }
- \tl_set:Nx \l_tmpa_tl
- { \lua_now:n { piton.Parse(token.scan_string()) } { #1 } }
+ \bool_lazy_or:nnTF
+ \l__piton_break_lines_in_piton_bool
+ \l__piton_break_lines_in_Piton_bool
+ {
+ \tl_set:Nx \l_tmpa_tl
+ { \lua_now:n { piton.ParseTer(token.scan_string()) } { #1 } }
+ }
+ {
+ \tl_set:Nx \l_tmpa_tl
+ { \lua_now:n { piton.Parse(token.scan_string()) } { #1 } }
+ }
\bool_if:NT \l__piton_show_spaces_bool
{ \regex_replace_all:nnN { \x20 } { ␣ } \l_tmpa_tl } % U+2423
\l_tmpa_tl
@@ -473,8 +496,17 @@
\cs_set_protected:Npn \__piton_end_line: { }
\cs_set_protected:Npn \__piton_newline:
{ \msg_fatal:nn { piton } { cr~not~allowed } }
- \tl_set:Nx \l_tmpa_tl
- { \lua_now:n { piton.Parse(token.scan_string()) } { #1 } }
+ \bool_lazy_or:nnTF
+ \l__piton_break_lines_in_piton_bool
+ \l__piton_break_lines_in_Piton_bool
+ {
+ \tl_set:Nx \l_tmpa_tl
+ { \lua_now:n { piton.ParseTer(token.scan_string()) } { #1 } }
+ }
+ {
+ \tl_set:Nx \l_tmpa_tl
+ { \lua_now:n { piton.Parse(token.scan_string()) } { #1 } }
+ }
\bool_if:NT \l__piton_show_spaces_bool
{ \regex_replace_all:nnN { \x20 } { ␣ } \l_tmpa_tl } % U+2423
\l_tmpa_tl
@@ -482,6 +514,7 @@
}
\cs_new:Npn \__piton_pre_env:
{
+ \automatichyphenmode = 1
\int_gincr:N \g__piton_env_int
\tl_gclear:N \g__piton_aux_tl
\cs_if_exist_use:c { c__piton _ \int_use:N \g__piton_env_int _ tl }
@@ -492,6 +525,8 @@
\int_gzero:N \g__piton_line_int
\dim_zero:N \parindent
\dim_zero:N \lineskip
+ \dim_zero:N \parindent
+ \cs_set_eq:NN \label \__piton_label:n
}
\keys_define:nn { PitonInputFile }
{
@@ -500,16 +535,22 @@
last-line .int_set:N = \l__piton_last_line_int ,
last-line .value_required:n = true ,
}
-\NewDocumentCommand { \PitonInputFile } { O { } m }
+\NewDocumentCommand { \PitonInputFile } { d < > O { } m }
{
+ \tl_if_novalue:nF { #1 }
+ {
+ \bool_if:NTF \c__piton_beamer_bool
+ { \begin { uncoverenv } < #1 > }
+ { \msg_error:nn { piton } { overlay~without~beamer } }
+ }
\group_begin:
\int_zero_new:N \l__piton_first_line_int
\int_zero_new:N \l__piton_last_line_int
\int_set_eq:NN \l__piton_last_line_int \c_max_int
- \keys_set:nn { PitonInputFile } { #1 }
+ \keys_set:nn { PitonInputFile } { #2 }
\__piton_pre_env:
\mode_if_vertical:TF \mode_leave_vertical: \newline
- \lua_now:n { piton.CountLinesFile(token.scan_argument()) } { #2 }
+ \lua_now:n { piton.CountLinesFile(token.scan_argument()) } { #3 }
\bool_lazy_and:nnT \l__piton_left_margin_auto_bool \l__piton_line_numbers_bool
{
\hbox_set:Nn \l_tmpa_box
@@ -523,7 +564,7 @@
{
\lua_now:n
{ piton.CountNonEmptyLinesFile(token.scan_argument()) }
- { #2 }
+ { #3 }
\int_to_arabic:n
{ \g__piton_visual_line_int + \l__piton_nb_non_empty_lines_int }
}
@@ -534,20 +575,22 @@
\bool_if:NT \c__piton_footnote_bool { \begin { savenotes } }
\vtop \bgroup
\lua_now:e
- { piton.ParseFile(token.scan_argument(),
+ {
+ piton.ParseFile(token.scan_argument() ,
\int_use:N \l__piton_first_line_int ,
\int_use:N \l__piton_last_line_int )
}
- { #2 }
+ { #3 }
\egroup
\bool_if:NT \c__piton_footnote_bool { \end { savenotes } }
\__piton_width_to_aux:
\group_end:
+ \tl_if_novalue:nF { #1 }
+ { \bool_if:NT \c__piton_beamer_bool { \end { uncoverenv } } }
\__piton_write_aux:
}
\NewDocumentCommand { \NewPitonEnvironment } { m m m m }
{
- \dim_zero:N \parindent
\use:x
{
\cs_set_protected:Npn
@@ -613,7 +656,17 @@
{ #4 }
\AddToHook { env / #1 / begin } { \char_set_catcode_other:N \^^M }
}
-\NewPitonEnvironment { Piton } { } { } { }
+\bool_if:NTF \c__piton_beamer_bool
+ {
+ \NewPitonEnvironment { Piton } { d < > }
+ {
+ \IfValueTF { #1 }
+ { \begin { uncoverenv } < #1 > }
+ { \begin { uncoverenv } }
+ }
+ { \end { uncoverenv } }
+ }
+ { \NewPitonEnvironment { Piton } { } { } { } }
\NewDocumentCommand { \PitonStyle } { m } { \use:c { pitonStyle #1 } }
\NewDocumentCommand { \SetPitonStyle } { } { \keys_set:nn { piton / Styles } }
\cs_new_protected:Npn \__piton_math_scantokens:n #1
@@ -738,6 +791,45 @@
\token_to_str:N \piton\ but~there~is~no~environment~
{piton}.~This~error~is~fatal.
}
+\msg_new:nnnn { piton } { Unknown~key~for~PitonOptions }
+ {
+ Unknown~key. \\
+ The~key~'\l_keys_key_str'~is~unknown~for~\token_to_str:N \PitonOptions.~
+ It~will~be~ignored.\\
+ For~a~list~of~the~available~keys,~type~H~<return>.
+ }
+ {
+ The~available~keys~are~(in~alphabetic~order):~
+ all-line-numbers,~
+ auto-gobble,~
+ background-color,~
+ break-lines,~
+ break-lines-in-piton,~
+ break-lines-in-Piton,~
+ continuation-symbol,~
+ continuation-symbol-on-indentation,~
+ end-of-broken-line,~
+ env-gobble,~
+ gobble,~
+ indent-broken-lines,~
+ left-margin,~
+ line-numbers,~
+ prompt-background-color,~
+ resume,~
+ show-spaces,~
+ show-spaces-in-strings,~
+ slim,~
+ splittable,~
+ tabs-auto-gobble~
+ and~tab-size.
+ }
+\msg_new:nnn { piton } { label~with~lines~numbers }
+ {
+ You~can't~use~the~command~\token_to_str:N \label\
+ because~the~key~'line-numbers'~(or~'all-line-numbers')~
+ is~not~active.\\
+ If~you~go~on,~that~command~will~ignored.
+ }
\msg_new:nnn { piton } { cr~not~allowed }
{
You~can't~put~any~carriage~return~in~the~argument~
@@ -747,6 +839,13 @@
corresponding~environment.\\
That~error~is~fatal.
}
+\msg_new:nnn { piton } { overlay~without~beamer }
+ {
+ You~can't~use~an~argument~<...>~for~your~command~
+ \token_to_str:N \PitonInputFile\ because~you~are~not~
+ in~Beamer.\\
+ If~you~go~on,~that~argument~will~be~ignored.
+ }
\ExplSyntaxOff
\RequirePackage{luacode}
\begin{luacode*}
@@ -780,7 +879,8 @@ local Escape =
* L ( ( 1 - P(piton_end_escape) ) ^ 1 )
* P(piton_end_escape)
lpeg.locale(lpeg)
-local alpha, digit, space = lpeg.alpha, lpeg.digit, lpeg.space
+local alpha, digit = lpeg.alpha, lpeg.digit
+local space = P " "
local letter = alpha + P "_"
+ P "â" + P "à" + P "ç" + P "é" + P "è" + P "ê" + P "ë" + P "ï" + P "î"
+ P "ô" + P "û" + P "ü" + P "Â" + P "À" + P "Ç" + P "É" + P "È" + P "Ê"
@@ -802,15 +902,14 @@ then Word = K ( ( ( 1 - space - P(piton_begin_escape) - P(piton_end_escape) )
- S "'\"\r[()]" - digit ) ^ 1 )
else Word = K ( ( ( 1 - space ) - S "'\"\r[()]" - digit ) ^ 1 )
end
-local Space = K ( ( space - P "\r" ) ^ 1 )
+local Space = ( K " " ) ^ 1
-local SkipSpace = K ( ( space - P "\r" ) ^ 0 )
+local SkipSpace = ( K " " ) ^ 0
local Punct = K ( S ".,:;!" )
-local Tab = P "\t" * Lc ( '\\l__piton_tab_tl' )
-local SpaceIndentation =
- Lc ( '\\__piton_an_indentation_space:' ) * K " "
+local Tab = P "\t" * Lc ( '\\l__piton_tab_tl' )
+local SpaceIndentation = Lc ( '\\__piton_an_indentation_space:' ) * ( K " " )
local Delim = K ( S "[()]" )
local Operator =
K ( P "!=" + P "<>" + P "==" + P "<<" + P ">>" + P "<=" + P ">=" + P ":="
@@ -914,12 +1013,12 @@ local DoubleLongInterpol =
* K ( ( 1 - S "}:\r" - P "\"\"\"" ) ^ 0 , 'Interpol.Inside' )
* K ( P ":" * (1 - S "}:\r" - P "\"\"\"" ) ^ 0 ) ^ -1
* K ( P "}" , 'String.Interpol' )
-local VisualSpace = P " " * Lc "\\l__piton_space_tl"
+local VisualSpace = space * Lc "\\l__piton_space_tl"
local SingleShortPureString =
- ( K ( ( P "\\'" + P "{{" + P "}}" + 1 - S " {}'" ) ^ 1 ) + VisualSpace ) ^ 1
+ ( VisualSpace + K ( ( P "\\'" + P "{{" + P "}}" + 1 - S " {}'" ) ^ 1 ) ) ^ 1
local DoubleShortPureString =
- ( K ( ( P "\\\"" + P "{{" + P "}}" + 1 - S " {}\"" ) ^ 1 ) + VisualSpace ) ^ 1
+ ( VisualSpace + K ( ( P "\\\"" + P "{{" + P "}}" + 1 - S " {}\"" ) ^ 1 ) ) ^ 1
local SingleLongPureString =
K ( ( 1 - P "'''" - S "{}'\r" ) ^ 1 )
@@ -1039,6 +1138,7 @@ then
* P "\r"
) ^ 0
end
+local Prompt = ( # ( P ">>>" + P "..." ) * Lc ( '\\__piton_prompt:' ) ) ^ -1
local EOL
if piton_beamer
then
@@ -1051,6 +1151,7 @@ EOL =
Lc ( '\\__piton_end_line:' )
* BeamerEndEnvironments
* BeamerBeginEnvironments
+ * Prompt
* Lc ( '\\__piton_newline: \\__piton_begin_line:' )
)
*
@@ -1060,9 +1161,11 @@ EOL =
P "\r"
*
(
- ( space^0 * -1 )
+ ( space ^ 0 * -1 )
+
- Lc ( '\\__piton_end_line: \\__piton_newline: \\__piton_begin_line:' )
+ Lc ( '\\__piton_end_line:' )
+ * Prompt
+ * Lc ( '\\__piton_newline: \\__piton_begin_line:' )
)
*
SpaceIndentation ^ 0
@@ -1133,7 +1236,9 @@ local DoubleLongString =
local LongString = SingleLongString + DoubleLongString
local StringDoc =
K ( P "\"\"\"" , 'String.Doc' )
- * ( K ( (1 - P "\"\"\"" - P "\r" ) ^ 0 , 'String.Doc' ) * EOL * Tab ^0 ) ^ 0
+ * ( K ( (1 - P "\"\"\"" - P "\r" ) ^ 0 , 'String.Doc' ) * EOL
+ * Tab ^ 0
+ ) ^ 0
* K ( ( 1 - P "\"\"\"" - P "\r" ) ^ 0 * P "\"\"\"" , 'String.Doc' )
local CommentMath =
P "$" * K ( ( 1 - S "$\r" ) ^ 1 , 'Comment.Math' ) * P "$"
@@ -1200,12 +1305,11 @@ local Set =
* ItemOfSet * ( K ( P "," ) * ItemOfSet ) ^ 0
* K ( P "}" )
local ExceptionInConsole = Exception * K ( ( 1 - P "\r" ) ^ 0 ) * EOL
-UserEnvironments = P ( true )
MainLoop =
( ( space^1 * -1 )
+ EOL
- + Tab
+ Space
+ + Tab
+ Escape
+ CommentLaTeX
+ Beamer
@@ -1222,10 +1326,10 @@ MainLoop =
+ RaiseException
+ DefFunction
+ DefClass
- + Keyword * ( Space + Punct + Delim + EOL + -1)
+ + Keyword * ( Space + Punct + Delim + EOL + -1 )
+ Decorator
- + OperatorWord * ( Space + Punct + Delim + EOL + -1)
- + Builtin * ( Space + Punct + Delim + EOL + -1)
+ + OperatorWord * ( Space + Punct + Delim + EOL + -1 )
+ + Builtin * ( Space + Punct + Delim + EOL + -1 )
+ Identifier
+ Number
+ Word
@@ -1237,7 +1341,7 @@ function piton.defSyntaxPython()
Ct (
( ( space - P "\r" ) ^0 * P "\r" ) ^ -1
* BeamerBeginEnvironments
- * UserEnvironments
+ * Prompt
* Lc ( '\\__piton_begin_line:' )
* SpaceIndentation ^ 0
* MainLoop
@@ -1248,13 +1352,9 @@ end
piton.defSyntaxPython()
function piton.Parse(code)
- local t = SyntaxPython : match ( code ) -- match is a method of the LPEG
+ local t = SyntaxPython : match ( code )
for _ , s in ipairs(t) do tex.tprint(s) end
end
-function piton.pitonParse(code)
- local s = ( Cs ( ( P '##' / '#' + 1 ) ^ 0 ) ) : match ( code )
- return piton.Parse(s)
-end
function piton.ParseFile(name,first_line,last_line)
s = ''
local i = 0
@@ -1267,6 +1367,15 @@ function piton.ParseFile(name,first_line,last_line)
end
piton.Parse(s)
end
+function piton.ParseBis(code)
+ local s = ( Cs ( ( P '##' / '#' + 1 ) ^ 0 ) ) : match ( code )
+ return piton.Parse(s)
+end
+function piton.ParseTer(code)
+ local s = ( Cs ( ( P '\\__piton_breakable_space:' / ' ' + 1 ) ^ 0 ) )
+ : match ( code )
+ return piton.Parse(s)
+end
local function gobble(n,code)
function concat(acc,new_value)
return acc .. new_value