diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2018-04-03 20:47:38 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2018-04-03 20:47:38 -0700 |
commit | afad01168d6506a828eb7cd76e5e06ef02733501 (patch) | |
tree | d3f3f753882c0ddcbeb54133a4277e9ebb1a6572 /parser.y | |
parent | 7bc150f6d87b836b7690f8d73ee815ea8c718b13 (diff) | |
download | txr-afad01168d6506a828eb7cd76e5e06ef02733501.tar.gz txr-afad01168d6506a828eb7cd76e5e06ef02733501.tar.bz2 txr-afad01168d6506a828eb7cd76e5e06ef02733501.zip |
parser: avoid consing for buf literals.
* parser.y (buflit, buflit_items): Don't cons up a list of
bytes in buflit_items which are then assembled into a
buffer. Rather, the buflit_items rules construct and fill a
buffer object directly. The buflit rule then just has to
signal the end of the buffer literal to the lexer, and trim
the buffer to the actual size. We will need this for
efficient loading of compiled files, in which the virtual
machine code is represented as a buffer literal.
Diffstat (limited to 'parser.y')
-rw-r--r-- | parser.y | 19 |
1 files changed, 7 insertions, 12 deletions
@@ -1232,23 +1232,18 @@ wordsqlit : '`' { $$ = nil; } buflit : HASH_B_QUOTE '\'' { $$ = make_buf(zero, nil, nil); end_of_buflit(scnr); } - | HASH_B_QUOTE buflit_items '\'' { val len = length($2); - val bytes = nreverse($2); - val buf = make_buf(len, nil, nil); - cnum i; - end_of_buflit(scnr); - - for (i = 0; i < c_num(len); i++) - { buf_put_u8(buf, num(i), - pop(&bytes)); } - $$ = buf; } + | HASH_B_QUOTE buflit_items '\'' { end_of_buflit(scnr); + buf_trim($2); + $$ = $2; } | HASH_B_QUOTE error { yyerr("unterminated buffer literal"); end_of_buflit(scnr); yyerrok; } ; -buflit_items : buflit_items buflit_item { $$ = cons($2, $1); } - | buflit_item { $$ = cons($1, nil); } +buflit_items : buflit_items buflit_item { buf_put_u8($1, length_buf($$), $2); + $$ = $1; } + | buflit_item { $$ = make_buf(zero, nil, num_fast(512)); + buf_put_u8($$, zero, $1); } ; buflit_item : LITCHAR LITCHAR { $$ = num($1 << 4 | $2); } |