From a559c25918b1466cdb50c9f978a86f01be0bac10 Mon Sep 17 00:00:00 2001 From: Larry Wall Date: Wed, 27 Jan 1988 22:18:25 +0000 Subject: perl 1.0 patch 8: perl needed an eval operator and a symbolic debugger I didn't add an eval operator to the original perl because I hadn't thought of any good uses for it. Recently I thought of some. Along with creating the eval operator, this patch introduces a symbolic debugger for perl scripts, which makes use of eval to interpret some debugging commands. Having eval also lets me emulate awk's FOO=bar command line behavior with a line such as the one a2p now inserts at the beginning of translated scripts. --- Makefile.SH | 9 +- arg.c | 12 ++- arg.h | 11 ++- cmd.h | 6 +- patchlevel.h | 2 +- perl.h | 10 +- perl.y | 10 +- perldb | 296 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ perldb.man | 119 ++++++++++++++++++++++++ perly.c | 175 ++++++++++++++++++++++++++++++++--- search.c | 7 +- stab.c | 11 ++- t/base.lex | 13 ++- t/op.eval | 20 ++++ util.c | 10 +- x2p/a2py.c | 9 +- x2p/walk.c | 11 ++- 17 files changed, 690 insertions(+), 41 deletions(-) create mode 100644 perldb create mode 100644 perldb.man create mode 100644 t/op.eval diff --git a/Makefile.SH b/Makefile.SH index fc05ca2b6a..a486289535 100644 --- a/Makefile.SH +++ b/Makefile.SH @@ -14,9 +14,12 @@ case "$0" in esac echo "Extracting Makefile (with variable substitutions)" cat >Makefile <>Makefile <<'!NO!SUBS!' -public = perl +public = perl perldb private = -manpages = perl.man +manpages = perl.man perldb.man util = diff --git a/arg.c b/arg.c index 728f44d819..df4887ad3a 100644 --- a/arg.c +++ b/arg.c @@ -1,8 +1,8 @@ -/* $Header: arg.c,v 1.0.1.3 88/01/26 12:30:33 root Exp $ +/* $Header: arg.c,v 1.0.1.4 88/01/28 10:22:06 root Exp $ * * $Log: arg.c,v $ - * Revision 1.0.1.3 88/01/26 12:30:33 root - * patch 6: sprintf didn't finish processing format string when out of args. + * Revision 1.0.1.4 88/01/28 10:22:06 root + * patch8: added eval operator. * * Revision 1.0.1.2 88/01/24 03:52:34 root * patch 2: added STATBLKS dependencies. @@ -1190,6 +1190,7 @@ init_eval() opargs[O_UNSHIFT] = A(1,0,0); opargs[O_LINK] = A(1,1,0); opargs[O_REPEAT] = A(1,1,0); + opargs[O_EVAL] = A(1,0,0); } #ifdef VOIDSIG @@ -2092,6 +2093,11 @@ STR ***retary; /* where to return an array to, null if nowhere */ } value = (double)(ary->ary_fill + 1); break; + case O_EVAL: + str_sset(str, + do_eval(arg[1].arg_type != A_NULL ? sarg[1] : defstab->stab_val) ); + STABSET(str); + break; } #ifdef DEBUGGING dlevel--; diff --git a/arg.h b/arg.h index 2e1bd8a339..d442b02dfa 100644 --- a/arg.h +++ b/arg.h @@ -1,6 +1,9 @@ -/* $Header: arg.h,v 1.0 87/12/18 13:04:39 root Exp $ +/* $Header: arg.h,v 1.0.1.1 88/01/28 10:22:40 root Exp $ * * $Log: arg.h,v $ + * Revision 1.0.1.1 88/01/28 10:22:40 root + * patch8: added eval operator. + * * Revision 1.0 87/12/18 13:04:39 root * Initial revision * @@ -111,7 +114,8 @@ #define O_UNSHIFT 102 #define O_LINK 103 #define O_REPEAT 104 -#define MAXO 105 +#define O_EVAL 105 +#define MAXO 106 #ifndef DOINIT extern char *opname[]; @@ -222,7 +226,8 @@ char *opname[] = { "UNSHIFT", "LINK", "REPEAT", - "105" + "EVAL", + "106" }; #endif diff --git a/cmd.h b/cmd.h index 9eb4a8f79d..9a019f2c74 100644 --- a/cmd.h +++ b/cmd.h @@ -1,6 +1,9 @@ -/* $Header: cmd.h,v 1.0 87/12/18 13:04:59 root Exp $ +/* $Header: cmd.h,v 1.0.1.1 88/01/28 10:23:07 root Exp $ * * $Log: cmd.h,v $ + * Revision 1.0.1.1 88/01/28 10:23:07 root + * patch8: added eval_root for eval operator. + * * Revision 1.0 87/12/18 13:04:59 root * Initial revision * @@ -106,6 +109,7 @@ struct cmd { #define Nullcmd Null(CMD*) EXT CMD *main_root INIT(Nullcmd); +EXT CMD *eval_root INIT(Nullcmd); EXT struct compcmd { CMD *comp_true; diff --git a/patchlevel.h b/patchlevel.h index e19cd94440..a6997a9a35 100644 --- a/patchlevel.h +++ b/patchlevel.h @@ -1 +1 @@ -#define PATCHLEVEL 7 +#define PATCHLEVEL 8 diff --git a/perl.h b/perl.h index 751b8cdc61..9b877f3e30 100644 --- a/perl.h +++ b/perl.h @@ -1,6 +1,9 @@ -/* $Header: perl.h,v 1.0.1.2 88/01/24 03:53:47 root Exp $ +/* $Header: perl.h,v 1.0.1.3 88/01/28 10:24:17 root Exp $ * * $Log: perl.h,v $ + * Revision 1.0.1.3 88/01/28 10:24:17 root + * patch8: added eval operator. + * * Revision 1.0.1.2 88/01/24 03:53:47 root * patch 2: hid str_peek() in #ifdef DEBUGGING. * @@ -103,7 +106,8 @@ ARG *flipflip(); STR *arg_to_str(); STR *str_new(); STR *stab_str(); -STR *eval(); +STR *eval(); /* this evaluates expressions */ +STR *do_eval(); /* this evaluates eval operator */ FCMD *load_format(); @@ -164,6 +168,7 @@ EXT char *inplace INIT(Nullch); EXT char tokenbuf[256]; EXT int expectterm INIT(TRUE); EXT int lex_newlines INIT(FALSE); +EXT int in_eval INIT(FALSE); FILE *popen(); /* char *str_get(); */ @@ -196,6 +201,7 @@ EXT struct loop { EXT int loop_ptr INIT(-1); EXT jmp_buf top_env; +EXT jmp_buf eval_env; EXT char *goto_targ INIT(Nullch); /* cmd_exec gets strange when set */ diff --git a/perl.y b/perl.y index 16f8a9aa96..b9a7a8e30e 100644 --- a/perl.y +++ b/perl.y @@ -1,6 +1,9 @@ -/* $Header: perl.y,v 1.0 87/12/18 15:48:59 root Exp $ +/* $Header: perl.y,v 1.0.1.1 88/01/28 10:25:31 root Exp $ * * $Log: perl.y,v $ + * Revision 1.0.1.1 88/01/28 10:25:31 root + * patch8: added eval operator. + * * Revision 1.0 87/12/18 15:48:59 root * Initial revision * @@ -97,7 +100,10 @@ char *tokename[] = { %% /* RULES */ prog : lineseq - { main_root = block_head($1); } + { if (in_eval) + eval_root = block_head($1); + else + main_root = block_head($1); } ; compblock: block CONTINUE block diff --git a/perldb b/perldb new file mode 100644 index 0000000000..d548f7299d --- /dev/null +++ b/perldb @@ -0,0 +1,296 @@ +#!/bin/perl + +# $Header: perldb,v 1.0.1.1 88/01/28 10:27:16 root Exp $ +# +# $Log: perldb,v $ +# Revision 1.0.1.1 88/01/28 10:27:16 root +# patch8: created this file. +# +# + +$tmp = "/tmp/pdb$$"; # default temporary file, -o overrides. + +# parse any switches + +while ($ARGV[0] =~ /^-/) { + $_ = shift; + /^-o$/ && ($tmp = shift,next); + die "Unrecognized switch: $_"; +} + +$filename = shift; +die "Usage: perldb [-o output] scriptname arguments" unless $filename; + +open(script,$filename) || die "Can't find $filename"; + +open(tmp, ">$tmp") || die "Can't make temp script"; + +$perl = '/bin/perl'; +$init = 1; +$state = 'statement'; + +# now translate script to contain DB calls at the appropriate places + +while (