Commit 7e57da12 by James A. Morrison

lex.l: Remove random whitespace.

2004-10-02  James A. Morrison  <phython@gcc.gnu.org>

        * lex.l: Remove random whitespace.
        * parse.y: Reformat copyright notice.  Indent declarations.
        Wrap long lines, unwrap short lines.
        * tree1.c: Reformat copyright notice.  Wrap long lines.
        Remove random whitespace.
        (lookup_tree_name): Use LOCATION_LINE.
        * treetree.c: Reformat copyright notice.  Wrap long lines.
        Remove random whitespace.

From-SVN: r88428
parent 1abb828a
2004-10-02 James A. Morrison <phython@gcc.gnu.org>
* lex.l: Remove random whitespace.
* parse.y: Reformat copyright notice. Indent declarations.
Wrap long lines, unwrap short lines.
* tree1.c: Reformat copyright notice. Wrap long lines.
Remove random whitespace.
(lookup_tree_name): Use LOCATION_LINE.
* treetree.c: Reformat copyright notice. Wrap long lines.
Remove random whitespace.
2004-10-01 James A. Morrison <phython@gcc.gnu.org> 2004-10-01 James A. Morrison <phython@gcc.gnu.org>
* parse.y (ELSE): Set tok to $1. * parse.y (ELSE): Set tok to $1.
......
...@@ -29,9 +29,7 @@ ...@@ -29,9 +29,7 @@
--------------------------------------------------------------------- ---------------------------------------------------------------------
Written by Tim Josling 1999-2001, based in part on other parts of Written by Tim Josling 1999-2001, based in part on other parts of
the GCC compiler. the GCC compiler. */
*/
%{ %{
#include "config.h" #include "config.h"
...@@ -51,7 +49,7 @@ extern int option_lexer_trace; ...@@ -51,7 +49,7 @@ extern int option_lexer_trace;
int yylex (void); int yylex (void);
void update_yylval (int a); void update_yylval (int a);
static int next_tree_charno=1; static int next_tree_charno = 1;
static void update_lineno_charno (void); static void update_lineno_charno (void);
static void dump_lex_value (int lexret); static void dump_lex_value (int lexret);
...@@ -254,7 +252,7 @@ void ...@@ -254,7 +252,7 @@ void
update_yylval (int a) update_yylval (int a)
{ {
struct prod_token_parm_item * tok; struct prod_token_parm_item * tok;
tok=yylval; tok = yylval;
tok->category = token_category; tok->category = token_category;
tok->type = a; tok->type = a;
......
%{ /* -*- c -*- emacs mode c */ /* -*- c -*- emacs mode c */
/* /* TREELANG Compiler parser.
TREELANG Compiler parser. ---------------------------------------------------------------------
--------------------------------------------------------------------- Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004 This program is free software; you can redistribute it and/or modify it
Free Software Foundation, Inc. under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
This program is free software; you can redistribute it and/or modify it This program is distributed in the hope that it will be useful,
under the terms of the GNU General Public License as published by the but WITHOUT ANY WARRANTY; without even the implied warranty of
Free Software Foundation; either version 2, or (at your option) any MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
later version. GNU General Public License for more details.
This program is distributed in the hope that it will be useful, You should have received a copy of the GNU General Public License
but WITHOUT ANY WARRANTY; without even the implied warranty of along with this program; if not, write to the Free Software
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the Foundation, 59 Temple Place - Suite 330,
GNU General Public License for more details. Boston, MA 02111-1307, USA.
You should have received a copy of the GNU General Public License In other words, you are welcome to use, share and improve this program.
along with this program; if not, write to the Free Software You are forbidden to forbid anyone else to use, share and improve
Foundation, 59 Temple Place - Suite 330, what you give them. Help stamp out software-hoarding!
Boston, MA 02111-1307, USA.
In other words, you are welcome to use, share and improve this program. ---------------------------------------------------------------------
You are forbidden to forbid anyone else to use, share and improve
what you give them. Help stamp out software-hoarding!
--------------------------------------------------------------------- Written by Tim Josling 1999-2001, based in part on other parts of
the GCC compiler. */
Written by Tim Josling 1999-2001, based in part on other parts of /* Grammar Conflicts
the GCC compiler.
*/
/*
Grammar Conflicts
***************** *****************
There are no conflicts in this grammar. Please keep it that way. */
There are no conflicts in this grammar. Please keep it that way. %{
*/
#include "config.h" #include "config.h"
#include "system.h" #include "system.h"
#include "coretypes.h" #include "coretypes.h"
...@@ -57,44 +49,46 @@ ...@@ -57,44 +49,46 @@
#define YYPRINT(file, type, value) print_token (file, type, value) #define YYPRINT(file, type, value) print_token (file, type, value)
#define YYERROR_VERBOSE YES #define YYERROR_VERBOSE YES
/* My yylex routine used to intercept calls to flex generated code, to /* My yylex routine used to intercept calls to flex generated code, to
record lex time. */ record lex time. */
int yylex (void); int yylex (void);
static inline int my_yylex (void); static inline int my_yylex (void);
/* Call lex, but ensure time is charged to TV_LEX. */
static inline int /* Call lex, but ensure time is charged to TV_LEX. */
my_yylex (void) static inline int
{ my_yylex (void)
{
int res; int res;
timevar_push (TV_LEX); timevar_push (TV_LEX);
res = yylex (); res = yylex ();
timevar_pop (TV_LEX); timevar_pop (TV_LEX);
return res; return res;
} }
#define yylex my_yylex #define yylex my_yylex
extern int option_parser_trace; extern int option_parser_trace;
/* Local prototypes. */ /* Local prototypes. */
static void yyerror (const char *error_message);
static void yyerror (const char *error_message); int yyparse (void);
int yyparse (void); void print_token (FILE * file, unsigned int type ATTRIBUTE_UNUSED,
void print_token (FILE * file, unsigned int type ATTRIBUTE_UNUSED, YYSTYPE value); YYSTYPE value);
static struct prod_token_parm_item *reverse_prod_list (struct prod_token_parm_item *old_first); static struct prod_token_parm_item *reverse_prod_list
static void ensure_not_void (unsigned int type, struct prod_token_parm_item* name); (struct prod_token_parm_item *old_first);
static int check_type_match (int type_num, struct prod_token_parm_item *exp); static void ensure_not_void (unsigned int type,
static int get_common_type (struct prod_token_parm_item *type1, struct prod_token_parm_item* name);
static int check_type_match (int type_num, struct prod_token_parm_item *exp);
static int get_common_type (struct prod_token_parm_item *type1,
struct prod_token_parm_item *type2); struct prod_token_parm_item *type2);
static struct prod_token_parm_item *make_integer_constant (struct prod_token_parm_item* value); static struct prod_token_parm_item *make_integer_constant
static struct prod_token_parm_item *make_plus_expression (struct prod_token_parm_item* value);
static struct prod_token_parm_item *make_plus_expression
(struct prod_token_parm_item* tok, struct prod_token_parm_item* op1, (struct prod_token_parm_item* tok, struct prod_token_parm_item* op1,
struct prod_token_parm_item* op2, int type_code, int prod_code); struct prod_token_parm_item* op2, int type_code, int prod_code);
static void set_storage (struct prod_token_parm_item *prod); static void set_storage (struct prod_token_parm_item *prod);
/* File global variables. */
static struct prod_token_parm_item *current_function=NULL;
/* File global variables. */
static struct prod_token_parm_item *current_function = NULL;
%} %}
/* Not %raw - seems to have bugs. */ /* Not %raw - seems to have bugs. */
...@@ -191,7 +185,8 @@ storage typename NAME init_opt SEMICOLON { ...@@ -191,7 +185,8 @@ storage typename NAME init_opt SEMICOLON {
SYMBOL_TABLE_NAME (prod) = tok; SYMBOL_TABLE_NAME (prod) = tok;
EXPRESSION_TYPE (prod) = $2; EXPRESSION_TYPE (prod) = $2;
VAR_INIT (prod) = $4; VAR_INIT (prod) = $4;
NUMERIC_TYPE (prod) = NUMERIC_TYPE (( (struct prod_token_parm_item*)EXPRESSION_TYPE (prod))); NUMERIC_TYPE (prod) =
NUMERIC_TYPE (( (struct prod_token_parm_item*)EXPRESSION_TYPE (prod)));
ensure_not_void (NUMERIC_TYPE (prod), tok); ensure_not_void (NUMERIC_TYPE (prod), tok);
if (insert_tree_name (prod)) if (insert_tree_name (prod))
{ {
...@@ -219,7 +214,8 @@ storage typename NAME init_opt SEMICOLON { ...@@ -219,7 +214,8 @@ storage typename NAME init_opt SEMICOLON {
((struct prod_token_parm_item*)SYMBOL_TABLE_NAME (prod))->tp.tok.chars, ((struct prod_token_parm_item*)SYMBOL_TABLE_NAME (prod))->tp.tok.chars,
((struct prod_token_parm_item*)SYMBOL_TABLE_NAME (prod))->tp.tok.length, ((struct prod_token_parm_item*)SYMBOL_TABLE_NAME (prod))->tp.tok.length,
NUMERIC_TYPE (prod), NUMERIC_TYPE (prod),
VAR_INIT (prod)? ((struct prod_token_parm_item*)VAR_INIT (prod))->tp.pro.code:NULL, VAR_INIT (prod) ?
((struct prod_token_parm_item*)VAR_INIT (prod))->tp.pro.code : NULL,
tok->tp.tok.location); tok->tp.tok.location);
if (!prod->tp.pro.code) if (!prod->tp.pro.code)
abort (); abort ();
...@@ -242,7 +238,8 @@ typename NAME { ...@@ -242,7 +238,8 @@ typename NAME {
prod = make_production (PROD_VARIABLE_NAME, tok); prod = make_production (PROD_VARIABLE_NAME, tok);
SYMBOL_TABLE_NAME (prod) = $2; SYMBOL_TABLE_NAME (prod) = $2;
EXPRESSION_TYPE (prod) = $1; EXPRESSION_TYPE (prod) = $1;
NUMERIC_TYPE (prod) = NUMERIC_TYPE (( (struct prod_token_parm_item*)EXPRESSION_TYPE (prod))); NUMERIC_TYPE (prod) =
NUMERIC_TYPE (( (struct prod_token_parm_item*)EXPRESSION_TYPE (prod)));
ensure_not_void (NUMERIC_TYPE (prod), tok); ensure_not_void (NUMERIC_TYPE (prod), tok);
if (insert_tree_name (prod)) if (insert_tree_name (prod))
{ {
...@@ -268,7 +265,8 @@ storage typename NAME LEFT_PARENTHESIS parameters_opt RIGHT_PARENTHESIS SEMICOLO ...@@ -268,7 +265,8 @@ storage typename NAME LEFT_PARENTHESIS parameters_opt RIGHT_PARENTHESIS SEMICOLO
prod = make_production (PROD_FUNCTION_NAME, $3); prod = make_production (PROD_FUNCTION_NAME, $3);
SYMBOL_TABLE_NAME (prod) = $3; SYMBOL_TABLE_NAME (prod) = $3;
EXPRESSION_TYPE (prod) = $2; EXPRESSION_TYPE (prod) = $2;
NUMERIC_TYPE (prod) = NUMERIC_TYPE (( (struct prod_token_parm_item*)EXPRESSION_TYPE (prod))); NUMERIC_TYPE (prod) =
NUMERIC_TYPE (( (struct prod_token_parm_item*)EXPRESSION_TYPE (prod)));
PARAMETERS (prod) = reverse_prod_list ($5); PARAMETERS (prod) = reverse_prod_list ($5);
insert_tree_name (prod); insert_tree_name (prod);
STORAGE_CLASS_TOKEN (prod) = $1; STORAGE_CLASS_TOKEN (prod) = $1;
...@@ -307,7 +305,9 @@ storage typename NAME LEFT_PARENTHESIS parameters_opt RIGHT_PARENTHESIS SEMICOLO ...@@ -307,7 +305,9 @@ storage typename NAME LEFT_PARENTHESIS parameters_opt RIGHT_PARENTHESIS SEMICOLO
this_parms = my_malloc (sizeof (struct prod_token_parm_item)); this_parms = my_malloc (sizeof (struct prod_token_parm_item));
if (!this_parm_var->tp.pro.main_token) if (!this_parm_var->tp.pro.main_token)
abort (); abort ();
this_parms->tp.par.variable_name = this_parm_var->tp.pro.main_token->tp.tok.chars;
this_parms->tp.par.variable_name =
this_parm_var->tp.pro.main_token->tp.tok.chars;
this_parms->category = parameter_category; this_parms->category = parameter_category;
this_parms->type = NUMERIC_TYPE this_parms->type = NUMERIC_TYPE
(( (struct prod_token_parm_item*)EXPRESSION_TYPE (this_parm_var))); (( (struct prod_token_parm_item*)EXPRESSION_TYPE (this_parm_var)));
...@@ -326,8 +326,10 @@ storage typename NAME LEFT_PARENTHESIS parameters_opt RIGHT_PARENTHESIS SEMICOLO ...@@ -326,8 +326,10 @@ storage typename NAME LEFT_PARENTHESIS parameters_opt RIGHT_PARENTHESIS SEMICOLO
} }
FIRST_PARMS (prod) = first_parms; FIRST_PARMS (prod) = first_parms;
prod->tp.pro.code = tree_code_create_function_prototype prod->tp.pro.code =
(tok->tp.tok.chars, STORAGE_CLASS (prod), NUMERIC_TYPE (type), tree_code_create_function_prototype (tok->tp.tok.chars,
STORAGE_CLASS (prod),
NUMERIC_TYPE (type),
first_parms, tok->tp.tok.location); first_parms, tok->tp.tok.location);
} }
; ;
...@@ -592,8 +594,7 @@ INTEGER { ...@@ -592,8 +594,7 @@ INTEGER {
int type_code = get_common_type (op1, op2); int type_code = get_common_type (op1, op2);
if (!type_code) if (!type_code)
YYERROR; YYERROR;
$$ = make_plus_expression $$ = make_plus_expression (tok, op1, op2, type_code, EXP_PLUS);
(tok, op1, op2, type_code, EXP_PLUS);
} }
|expression tl_MINUS expression %prec tl_PLUS { |expression tl_MINUS expression %prec tl_PLUS {
struct prod_token_parm_item *tok = $2; struct prod_token_parm_item *tok = $2;
...@@ -602,8 +603,7 @@ INTEGER { ...@@ -602,8 +603,7 @@ INTEGER {
int type_code = get_common_type (op1, op2); int type_code = get_common_type (op1, op2);
if (!type_code) if (!type_code)
YYERROR; YYERROR;
$$ = make_plus_expression $$ = make_plus_expression (tok, op1, op2, type_code, EXP_MINUS);
(tok, op1, op2, type_code, EXP_MINUS);
} }
|expression EQUALS expression { |expression EQUALS expression {
struct prod_token_parm_item *tok = $2; struct prod_token_parm_item *tok = $2;
...@@ -695,8 +695,9 @@ NAME LEFT_PARENTHESIS expressions_with_commas RIGHT_PARENTHESIS { ...@@ -695,8 +695,9 @@ NAME LEFT_PARENTHESIS expressions_with_commas RIGHT_PARENTHESIS {
parms = tree_code_add_parameter (parms, var->tp.pro.code, exp->tp.pro.code); parms = tree_code_add_parameter (parms, var->tp.pro.code, exp->tp.pro.code);
} }
type = tree_code_get_type (NUMERIC_TYPE (prod)); type = tree_code_get_type (NUMERIC_TYPE (prod));
prod->tp.pro.code = tree_code_get_expression prod->tp.pro.code = tree_code_get_expression (EXP_FUNCTION_INVOCATION, type,
(EXP_FUNCTION_INVOCATION, type, proto->tp.pro.code, parms, NULL); proto->tp.pro.code, parms,
NULL);
$$ = prod; $$ = prod;
} }
; ;
...@@ -746,7 +747,8 @@ NAME { ...@@ -746,7 +747,8 @@ NAME {
YYERROR; YYERROR;
OP1 (prod) = $1; OP1 (prod) = $1;
prod->tp.pro.code = tree_code_get_expression (EXP_REFERENCE, type, prod->tp.pro.code =
tree_code_get_expression (EXP_REFERENCE, type,
symbol_table_entry->tp.pro.code, NULL, NULL); symbol_table_entry->tp.pro.code, NULL, NULL);
$$ = prod; $$ = prod;
} }
...@@ -853,7 +855,8 @@ ensure_not_void (unsigned int type, struct prod_token_parm_item* name) ...@@ -853,7 +855,8 @@ ensure_not_void (unsigned int type, struct prod_token_parm_item* name)
common type (min is signed int). */ common type (min is signed int). */
static int static int
get_common_type (struct prod_token_parm_item *type1, struct prod_token_parm_item *type2) get_common_type (struct prod_token_parm_item *type1,
struct prod_token_parm_item *type2)
{ {
if (NUMERIC_TYPE (type1) == UNSIGNED_INT) if (NUMERIC_TYPE (type1) == UNSIGNED_INT)
return UNSIGNED_INT; return UNSIGNED_INT;
...@@ -915,7 +918,8 @@ make_integer_constant (struct prod_token_parm_item* value) ...@@ -915,7 +918,8 @@ make_integer_constant (struct prod_token_parm_item* value)
NUMERIC_TYPE (prod) = SIGNED_INT; NUMERIC_TYPE (prod) = SIGNED_INT;
else else
NUMERIC_TYPE (prod) = UNSIGNED_INT; NUMERIC_TYPE (prod) = UNSIGNED_INT;
prod->tp.pro.code = tree_code_get_integer_value (tok->tp.tok.chars, tok->tp.tok.length); prod->tp.pro.code = tree_code_get_integer_value (tok->tp.tok.chars,
tok->tp.tok.length);
return prod; return prod;
} }
......
/* /* TREELANG Compiler almost main (tree1)
TREELANG Compiler almost main (tree1)
Called by GCC's toplev.c Called by GCC's toplev.c
Copyright (C) 1986, 87, 89, 92-96, 1997, 1999, 2000, 2001, 2002, 2003, 2004 Copyright (C) 1986, 87, 89, 92-96, 1997, 1999, 2000, 2001, 2002, 2003, 2004
...@@ -28,9 +26,7 @@ ...@@ -28,9 +26,7 @@
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
Written by Tim Josling 1999, 2000, 2001, based in part on other Written by Tim Josling 1999, 2000, 2001, based in part on other
parts of the GCC compiler. parts of the GCC compiler. */
*/
#include "config.h" #include "config.h"
#include "system.h" #include "system.h"
...@@ -232,19 +228,21 @@ lookup_tree_name (struct prod_token_parm_item *prod) ...@@ -232,19 +228,21 @@ lookup_tree_name (struct prod_token_parm_item *prod)
sanity_check (this_tok); sanity_check (this_tok);
if (tok->tp.tok.length != this_tok->tp.tok.length) if (tok->tp.tok.length != this_tok->tp.tok.length)
continue; continue;
if (memcmp (tok->tp.tok.chars, this_tok->tp.tok.chars, this_tok->tp.tok.length)) if (memcmp (tok->tp.tok.chars, this_tok->tp.tok.chars,
this_tok->tp.tok.length))
continue; continue;
if (option_parser_trace) if (option_parser_trace)
fprintf (stderr, "Found symbol %s (%i:%i) as %i \n", fprintf (stderr, "Found symbol %s (%i:%i) as %i \n",
tok->tp.tok.chars, tok->tp.tok.chars, LOCATION_LINE (tok->tp.tok.location),
tok->tp.tok.location.line, tok->tp.tok.charno, tok->tp.tok.charno, NUMERIC_TYPE (this));
NUMERIC_TYPE (this));
return this; return this;
} }
if (option_parser_trace) if (option_parser_trace)
fprintf (stderr, "Not found symbol %s (%i:%i) as %i \n", fprintf (stderr, "Not found symbol %s (%i:%i) as %i \n",
tok->tp.tok.chars, tok->tp.tok.chars, LOCATION_LINE (tok->tp.tok.location),
tok->tp.tok.location.line, tok->tp.tok.charno, tok->type); tok->tp.tok.charno, tok->type);
return NULL; return NULL;
} }
......
/* /* TREELANG Compiler interface to GCC's middle end (treetree.c)
TREELANG Compiler interface to GCC's middle end (treetree.c)
Called by the parser. Called by the parser.
If you want a working example of how to write a front end to GCC, If you want a working example of how to write a front end to GCC,
...@@ -21,7 +19,7 @@ ...@@ -21,7 +19,7 @@
Updated to function-at-a-time by James A. Morrison, 2004. Updated to function-at-a-time by James A. Morrison, 2004.
--------------------------------------------------------------------------- -----------------------------------------------------------------------
This program is free software; you can redistribute it and/or modify it This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the under the terms of the GNU General Public License as published by the
...@@ -42,12 +40,9 @@ ...@@ -42,12 +40,9 @@
You are forbidden to forbid anyone else to use, share and improve You are forbidden to forbid anyone else to use, share and improve
what you give them. Help stamp out software-hoarding! what you give them. Help stamp out software-hoarding!
--------------------------------------------------------------------------- ----------------------------------------------------------------------- */
*/
/* /* Assumption: garbage collection is never called implicitly. It will
Assumption: garbage collection is never called implicitly. It will
not be called 'at any time' when short of memory. It will only be not be called 'at any time' when short of memory. It will only be
called explicitly at the end of each function. This removes the called explicitly at the end of each function. This removes the
need for a *lot* of bother to ensure everything is in the mark trees need for a *lot* of bother to ensure everything is in the mark trees
...@@ -263,7 +258,8 @@ tree_code_if_start (tree exp, location_t loc) ...@@ -263,7 +258,8 @@ tree_code_if_start (tree exp, location_t loc)
{ {
tree cond_exp, cond; tree cond_exp, cond;
cond_exp = fold (build2 (NE_EXPR, boolean_type_node, exp, cond_exp = fold (build2 (NE_EXPR, boolean_type_node, exp,
fold (build1 (CONVERT_EXPR, TREE_TYPE (exp), integer_zero_node)))); fold (build1 (CONVERT_EXPR, TREE_TYPE (exp),
integer_zero_node))));
SET_EXPR_LOCATION (cond_exp, loc); SET_EXPR_LOCATION (cond_exp, loc);
cond = build3 (COND_EXPR, void_type_node, cond_exp, NULL_TREE, cond = build3 (COND_EXPR, void_type_node, cond_exp, NULL_TREE,
NULL_TREE); NULL_TREE);
...@@ -603,7 +599,6 @@ tree_code_create_variable (unsigned int storage_class, ...@@ -603,7 +599,6 @@ tree_code_create_variable (unsigned int storage_class,
TYPE_NAME (TREE_TYPE (var_decl)) = TYPE_NAME (var_type); TYPE_NAME (TREE_TYPE (var_decl)) = TYPE_NAME (var_type);
return pushdecl (copy_node (var_decl)); return pushdecl (copy_node (var_decl));
} }
...@@ -744,8 +739,8 @@ tree_code_get_expression (unsigned int exp_type, ...@@ -744,8 +739,8 @@ tree_code_get_expression (unsigned int exp_type,
{ {
tree fun_ptr; tree fun_ptr;
fun_ptr = fold (build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (op1)), fun_ptr = fold (build1 (ADDR_EXPR,
op1)); build_pointer_type (TREE_TYPE (op1)), op1));
ret1 = build3 (CALL_EXPR, type, fun_ptr, nreverse (op2), NULL_TREE); ret1 = build3 (CALL_EXPR, type, fun_ptr, nreverse (op2), NULL_TREE);
} }
break; break;
...@@ -773,8 +768,8 @@ tree_code_add_parameter (tree list, tree proto_exp, tree exp) ...@@ -773,8 +768,8 @@ tree_code_add_parameter (tree list, tree proto_exp, tree exp)
{ {
tree new_exp; tree new_exp;
new_exp = tree_cons (NULL_TREE, new_exp = tree_cons (NULL_TREE,
fold (build1 (CONVERT_EXPR, TREE_TYPE (proto_exp), exp)), fold (build1 (CONVERT_EXPR, TREE_TYPE (proto_exp),
NULL_TREE); exp)), NULL_TREE);
if (!list) if (!list)
return new_exp; return new_exp;
return chainon (new_exp, list); return chainon (new_exp, list);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment