9front - general discussion about 9front
 help / color / mirror / Atom feed
From: ori@eigenstate.org
To: 9front@9front.org
Subject: Re: [9front] rc: null list in concatenation line numbers
Date: Wed, 21 Oct 2020 18:18:28 -0700	[thread overview]
Message-ID: <9661591FC410B16CA272B221336B866C@eigenstate.org> (raw)
In-Reply-To: <71CE86A5EC086742886B6A2E7F09C255@eigenstate.org>

> Testing and review welcome.

Another iteration: This one caps the number of filenames
that we put into the name table. It's pointless to past
the name table past the maximum number of files that fit
into the location.

diff -r bdd5a746e8c5 sys/src/cmd/rc/code.c
--- a/sys/src/cmd/rc/code.c	Sun Oct 18 19:30:14 2020 -0700
+++ b/sys/src/cmd/rc/code.c	Wed Oct 21 18:15:06 2020 -0700
@@ -6,10 +6,12 @@
 #define	c0	t->child[0]
 #define	c1	t->child[1]
 #define	c2	t->child[2]
+code *codebuf;
 int codep, ncode;
 #define	emitf(x) ((codep!=ncode || morecode()), codebuf[codep].f = (x), codep++)
 #define	emiti(x) ((codep!=ncode || morecode()), codebuf[codep].i = (x), codep++)
 #define	emits(x) ((codep!=ncode || morecode()), codebuf[codep].s = (x), codep++)
+
 void stuffdot(int);
 char *fnstr(tree*);
 void outcode(tree*, int);
@@ -37,9 +39,9 @@
 int
 compile(tree *t)
 {
+	codep = 0;
 	ncode = 100;
-	codebuf = (code *)emalloc(ncode*sizeof codebuf[0]);
-	codep = 0;
+	codebuf = emalloc(ncode*sizeof codebuf[0]);
 	emiti(0);			/* reference count */
 	outcode(t, flag['e']?1:0);
 	if(nerror){
@@ -79,12 +81,28 @@
 void
 outcode(tree *t, int eflag)
 {
-	int p, q;
+	static int file, line;
+	int p, q, f, l;
 	tree *tt;
 	if(t==0)
 		return;
 	if(t->type!=NOT && t->type!=';')
 		runq->iflast = 0;
+	if(t->file != file || t->line != line){
+		file = t->file;
+		line = t->line;
+
+		/*
+		 * These are small enough that with a ton of sourcing,
+		 * overflow is a realistic risk. If we run out of files,
+		 * set to file 0, which is always '???'
+		 */
+		f = (t->file > LFMAX) ? 0 : t->file << LSHIFT;
+		l = (t->line > LMASK) ? -1 : t->line;
+
+		emitf(Xloc);
+		emiti(f|l);
+	}
 	switch(t->type){
 	default:
 		pfmt(err, "bad type %d in outcode\n", t->type);
diff -r bdd5a746e8c5 sys/src/cmd/rc/exec.c
--- a/sys/src/cmd/rc/exec.c	Sun Oct 18 19:30:14 2020 -0700
+++ b/sys/src/cmd/rc/exec.c	Wed Oct 21 18:15:06 2020 -0700
@@ -14,6 +14,7 @@
 	struct thread *p = new(struct thread);
 
 	p->code = codecopy(c);
+	p->loc = 0;
 	p->pc = pc;
 	p->argv = 0;
 	p->redir = p->startredir = runq?runq->redir:0;
@@ -205,6 +206,11 @@
 	pushlist();
 	argv0 = estrdup(argv[0]);
 	for(i = argc-1;i!=0;--i) pushword(argv[i]);
+
+	lexpath = erealloc(lexpath, sizeof(char*));
+	nlexpath = 1;
+	lexpath[0] = strdup("???");
+
 	for(;;){
 		if(flag['r'])
 			pfnc(err, runq);
@@ -953,10 +959,15 @@
 void
 Xerror(char *s)
 {
+	int f, l;
+
+	f = runq->loc >> LSHIFT;
+	l = runq->loc & LMASK;
+	assert(f >= 0 && f < nlexpath);
 	if(strcmp(argv0, "rc")==0 || strcmp(argv0, "/bin/rc")==0)
-		pfmt(err, "rc: %s: %r\n", s);
+		pfmt(err, "rc:%d: %s: %r\n", l, s);
 	else
-		pfmt(err, "rc (%s): %s: %r\n", argv0, s);
+		pfmt(err, "%s:%d: %s: %r\n", lexpath[f], l, s);
 	flush(err);
 	setstatus("error");
 	while(!runq->iflag) Xreturn();
@@ -965,10 +976,15 @@
 void
 Xerror1(char *s)
 {
+	int f, l;
+
+	f = runq->loc >> LSHIFT;
+	l = runq->loc & LMASK;
+	assert(f >= 0 && f < nlexpath);
 	if(strcmp(argv0, "rc")==0 || strcmp(argv0, "/bin/rc")==0)
-		pfmt(err, "rc: %s\n", s);
+		pfmt(err, "rc:%d: %s\n", l, s);
 	else
-		pfmt(err, "rc (%s): %s\n", argv0, s);
+		pfmt(err, "%s:%d: %s\n", lexpath[f], l, s);
 	flush(err);
 	setstatus("error");
 	while(!runq->iflag) Xreturn();
@@ -1025,3 +1041,10 @@
 {
 	globlist(runq->argv->words);
 }
+
+void
+Xloc(void)
+{
+	runq->loc = runq->code[runq->pc].i;
+	runq->pc++;
+}
diff -r bdd5a746e8c5 sys/src/cmd/rc/exec.h
--- a/sys/src/cmd/rc/exec.h	Sun Oct 18 19:30:14 2020 -0700
+++ b/sys/src/cmd/rc/exec.h	Wed Oct 21 18:15:06 2020 -0700
@@ -5,7 +5,7 @@
 extern void Xconc(void), Xcount(void), Xdelfn(void), Xdol(void), Xqw(void), Xdup(void);
 extern void Xexit(void), Xfalse(void), Xfn(void), Xfor(void), Xglob(void);
 extern void Xjump(void), Xmark(void), Xmatch(void), Xpipe(void), Xread(void);
-extern void Xrdwr(void);
+extern void Xrdwr(void), Xloc(void);
 extern void Xrdfn(void), Xunredir(void), Xstar(void), Xreturn(void), Xsubshell(void);
 extern void Xtrue(void), Xword(void), Xglobs(void), Xwrite(void), Xpipefd(void), Xcase(void);
 extern void Xlocal(void), Xunlocal(void), Xassign(void), Xsimple(void), Xpopm(void);
@@ -30,7 +30,7 @@
 struct redir{
 	char type;			/* what to do */
 	short from, to;			/* what to do it to */
-	struct redir *next;		/* what else to do (reverse order) */
+	redir *next;		/* what else to do (reverse order) */
 };
 #define	NSTATUS	ERRMAX			/* length of status (from plan 9) */
 /*
@@ -40,14 +40,15 @@
 #define	RDUP	2			/* dup2(from, to); */
 #define	RCLOSE	3			/* close(from); */
 struct thread{
-	union code *code;		/* code for this thread */
+	code *code;			/* code for this thread */
 	int pc;				/* code[pc] is the next instruction */
-	struct list *argv;		/* argument stack */
-	struct redir *redir;		/* redirection stack */
-	struct redir *startredir;	/* redir inheritance point */
-	struct var *local;		/* list of local variables */
+	int loc;			/* source code location */
+	list *argv;			/* argument stack */
+	redir *redir;			/* redirection stack */
+	redir *startredir;		/* redir inheritance point */
+	var *local;			/* list of local variables */
 	char *cmdfile;			/* file name in Xrdcmd */
-	struct io *cmdfd;		/* file descriptor for Xrdcmd */
+	io *cmdfd;			/* file descriptor for Xrdcmd */
 	int iflast;			/* static `if not' checking */
 	int eof;			/* is cmdfd at eof? */
 	int iflag;			/* interactive? */
@@ -55,7 +56,7 @@
 	int pid;			/* process for Xpipewait to wait for */
 	char status[NSTATUS];		/* status for Xpipewait */
 	tree *treenodes;		/* tree nodes created by this process */
-	thread *ret;		/* who continues when this finishes */
+	thread *ret;			/* who continues when this finishes */
 };
 thread *runq;
 code *codecopy(code*);
diff -r bdd5a746e8c5 sys/src/cmd/rc/lex.c
--- a/sys/src/cmd/rc/lex.c	Sun Oct 18 19:30:14 2020 -0700
+++ b/sys/src/cmd/rc/lex.c	Wed Oct 21 18:15:06 2020 -0700
@@ -25,6 +25,13 @@
 int doprompt = 1;
 int inquote;
 int incomm;
+int lastc;
+int ndot;
+int nerror;
+int lexline;
+int lexfile;
+char **lexpath;
+int nlexpath;
 /*
  * Look ahead in the input stream
  */
@@ -39,13 +46,14 @@
 /*
  * Consume the lookahead character.
  */
-
 int
 advance(void)
 {
 	int c = nextc();
 	lastc = future;
 	future = EOF;
+	if(c == '\n')
+		lexline++;
 	return c;
 }
 /*
diff -r bdd5a746e8c5 sys/src/cmd/rc/pfnc.c
--- a/sys/src/cmd/rc/pfnc.c	Sun Oct 18 19:30:14 2020 -0700
+++ b/sys/src/cmd/rc/pfnc.c	Wed Oct 21 18:15:06 2020 -0700
@@ -51,6 +51,7 @@
 	Xrdfn, "Xrdfn",
 	Xsimple, "Xsimple",
 	Xqw, "Xqw",
+	Xloc, "Xloc",
 0};
 
 void
diff -r bdd5a746e8c5 sys/src/cmd/rc/rc.h
--- a/sys/src/cmd/rc/rc.h	Sun Oct 18 19:30:14 2020 -0700
+++ b/sys/src/cmd/rc/rc.h	Wed Oct 21 18:15:06 2020 -0700
@@ -43,6 +43,8 @@
 	char	*str;
 	int	quoted;
 	int	iskw;
+	int	file;
+	int	line;
 	tree	*child[3];
 	tree	*next;
 };
@@ -54,6 +56,19 @@
 tree *simplemung(tree*), *heredoc(tree*);
 void freetree(tree*);
 tree *cmdtree;
+
+/*
+ * Locations are stored as instructions in the rc bytecode.
+ * To avoid wasting too much space, both the file and line
+ * is packed into a single integer, as
+ *     (file << LSHIFT) | line
+ * With 32 bit integers, this gives us 2048 filenames, with
+ * just over 1 million lines of code in each.
+ */
+#define LSHIFT	20
+#define LMASK	((1<<LSHIFT)-1)
+#define LFMAX	(1<<(8*sizeof(int)-LSHIFT-1))
+
 /*
  * The first word of any code vector is a reference count.
  * Always create a new reference to a code vector by calling codecopy(.).
@@ -126,10 +141,15 @@
  */
 #define	onebyte(c)	((c&0x80)==0x00)
 
-char **argp;
-char **args;
-int nerror;		/* number of errors encountered during compilation */
-int doprompt;		/* is it time for a prompt? */
+extern char **argp;
+extern char **args;
+extern int nerror;		/* number of errors encountered during compilation */
+extern int doprompt;		/* is it time for a prompt? */
+extern int lexfile;
+extern int lexline;
+extern char **lexpath;
+extern int nlexpath;
+
 /*
  * Which fds are the reading/writing end of a pipe?
  * Unfortunately, this can vary from system to system.
@@ -143,7 +163,7 @@
  * How many dot commands have we executed?
  * Used to ensure that -v flag doesn't print rcmain.
  */
-int ndot;
+extern int ndot;
+extern int lastc;
+extern int lastword;
 char *getstatus(void);
-int lastc;
-int lastword;
diff -r bdd5a746e8c5 sys/src/cmd/rc/simple.c
--- a/sys/src/cmd/rc/simple.c	Sun Oct 18 19:30:14 2020 -0700
+++ b/sys/src/cmd/rc/simple.c	Wed Oct 21 18:15:06 2020 -0700
@@ -11,7 +11,7 @@
  */
 int
 exitnext(void){
-	union code *c=&runq->code[runq->pc];
+	code *c=&runq->code[runq->pc];
 	while(c->f==Xpopredir || c->f==Xunlocal) c++;
 	return c->f==Xexit;
 }
@@ -294,7 +294,7 @@
 execdot(void)
 {
 	int iflag = 0;
-	int fd;
+	int fd, i;
 	list *av;
 	thread *p = runq;
 	char *zero, *file;
@@ -354,6 +354,22 @@
 		Xerror(".: can't open");
 		return;
 	}
+
+	lexline = 1;
+	for(i = 0; i < nlexpath; i++){
+		if(strcmp(lexpath[i], zero) == 0){
+			lexfile = i;
+			break;
+		}
+	}
+	if(i == nlexpath){
+		if(nlexpath < LFMAX){
+			lexpath = erealloc(lexpath, (nlexpath + 1)*sizeof(char*));
+			lexpath[nlexpath] = estrdup(zero);
+			lexfile = nlexpath++;
+		}else
+			lexfile = 0;
+	}
 	/* set up for a new command loop */
 	start(dotcmds, 1, (struct var *)0);
 	pushredir(RCLOSE, fd, 0);
diff -r bdd5a746e8c5 sys/src/cmd/rc/tree.c
--- a/sys/src/cmd/rc/tree.c	Sun Oct 18 19:30:14 2020 -0700
+++ b/sys/src/cmd/rc/tree.c	Wed Oct 21 18:15:06 2020 -0700
@@ -16,6 +16,8 @@
 	t->str = 0;
 	t->child[0] = t->child[1] = t->child[2] = 0;
 	t->next = treenodes;
+	t->file = lexfile;
+	t->line = lexline;
 	treenodes = t;
 	return t;
 }



  parent reply	other threads:[~2020-10-22  1:18 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-10-16  1:40 ori
2020-10-16  3:43 ` [9front] " Xiao-Yong Jin
2020-10-17  1:47   ` ori
2020-10-16  5:40 ` Iruatã Souza
2020-10-22  1:18 ` ori [this message]
2020-10-22 12:11   ` tlaronde
2020-10-25 20:29   ` ori
2020-10-25 23:18     ` cinap_lenrek
2020-10-26  1:00       ` ori
2020-10-25 23:41     ` cinap_lenrek
2020-10-26  1:33       ` ori
2020-10-26  7:36         ` cinap_lenrek
2020-10-28  3:16           ` ori
2020-10-28  9:50             ` cinap_lenrek
2020-10-28 17:59               ` ori
2020-10-31  1:55               ` ori

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=9661591FC410B16CA272B221336B866C@eigenstate.org \
    --to=ori@eigenstate.org \
    --cc=9front@9front.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).