shithub: mlisp

Download patch

ref: 442728dece582ebc742f771362acf4ea861a812f
parent: 3e8336c0ea2e6f70eb0b277f3d0927b114d0709c
author: aap <[email protected]>
date: Sun Aug 21 07:46:49 EDT 2022

restructure program feature

--- a/lisp.c
+++ b/lisp.c
@@ -703,8 +703,7 @@
 			return evbody(c->a->d, a);
 		}
 	}
-	err("error: no cond clause");
-	return nil;	/* make compiler happy */
+	return nil;
 }
 
 C*
@@ -1022,6 +1021,7 @@
 		fprintf(sysout, "→\n");
 	pdp = 0;
 	alist = nil;
+	memset(&prog, 0, sizeof(prog));
 	memset(&temlis, 0, sizeof(temlis));
 
 	eval_repl();
--- a/lisp.h
+++ b/lisp.h
@@ -139,6 +139,15 @@
 };
 extern Arglist largs;	/* LEXPR/LSUBR args */
 
+typedef struct Prog Prog;
+struct Prog
+{
+	C *prog;
+	C *pc;
+	C *ret;
+};
+extern Prog prog;
+
 extern C *noval;
 extern C *t;
 extern C *value;
--- a/subr.c
+++ b/subr.c
@@ -1,9 +1,4 @@
 #include "lisp.h"
-/*
-#include <limits.h>
-#include <float.h>
-#include <math.h>
-*/
 
 int
 floeq(flonum x, flonum y)
@@ -954,86 +949,44 @@
 
 
 /* Prog feature */
+Prog prog;
 
-typedef struct Prog Prog;
-struct Prog
-{
-	C *a;
-	C *go;
-	C *pc;
-	C *ret;
-};
-
-void
-setq_prog(Prog *prog, C *form)
-{
-	C *tt;
-	if(form == nil)
+C *go_fsubr(void){
+	C *t, *p;
+	if(prog.prog == nil)
+		err("error: not in prog");
+	if(alist[0] == nil)
 		err("error: arg count");
-	if(!atom(form->a))
-		err("error: no atom");
-	tt = assq(form->a, prog->a);
-	if(tt == nil)
-		err("error: undefined");
-	tt->d = eval(form->d->a, prog->a);
+	t = alist[0]->a;
+	while(!atom(t))
+		t = eval(t, alist[1]);
+	for(p = prog.prog; p != nil; p = p->d)
+		if(p->a == t){
+			prog.pc = p->d;
+			return nil;
+		}
+	err("undefined label");
+	return nil;	// hm...
 }
-
-void
-set_prog(Prog *prog, C *form)
-{
-	C *tt;
-	if(form == nil)
-		err("error: arg count");
-	tt = eval(form->a, prog->a);
-	if(!atom(tt))
-		err("error: no atom");
-	tt = assq(tt, prog->a);
-	if(tt == nil)
-		err("error: undefined");
-	tt->d = eval(form->d->a, prog->a);
+C *return_fsubr(void){
+	if(prog.prog == nil)
+		err("error: not in prog");
+	if(alist[0] == nil)
+		prog.ret = nil;
+	else
+		prog.ret = eval(alist[0]->a, alist[1]);
+	prog.pc = nil;
+	return nil;	// hm...
 }
 
-void
-progstmt(Prog *prog, C *form)
-{
-	C *tt;
-	C *pc;
-
-	if(atom(form))
-		{}
-	else if(form->a == setq)
-		setq_prog(prog, form->d);
-	else if(form->a == set)
-		set_prog(prog, form->d);
-	else if(form->a == cond){
-		for(form = form->d; form != nil; form = form->d)
-			if(eval(form->a->a, prog->a) != nil){
-				for(pc = form->a->d; pc != nil; pc = pc->d)
-					progstmt(prog, pc->a);
-				return;
-			}
-	}else if(form->a == go){
-		if(form->d == nil)
-			err("error: arg count");
-		if(tt = assq(form->d->a, prog->go), tt == nil)
-			err("error: undefined label");
-		prog->pc = tt->d;
-	}else if(form->a == retrn){
-		if(form->d == nil)
-			prog->ret = nil;
-		else
-			prog->ret = eval(form->d->a, prog->a);
-		prog->pc = nil;
-	}else
-		eval(form, prog->a);
-}
-
 C *prog_fsubr(void){
-	Prog prog;
+	Prog progsv;
 
-	C *p;
+	C *p, *a;
 	C **ap;
 
+	progsv = prog;
+	prog.prog = alist[0]->d;
 	prog.pc = alist[0]->d;
 
 	/* build a-list */
@@ -1043,28 +996,22 @@
 		*ap = cons(cons(p->a, nil), nil);
 		ap = &(*ap)->d;
 	}
-	*ap = alist[1];
-	alist[1] = temlis.a;
-	prog.a = alist[1];
+	*ap = alist[1];		/* nconc */
+	alist[1] = a = temlis.a;
 	temlis.a = nil;
 
-	/* build go-list */
-	for(p = prog.pc; p != nil; p = p->d)
-		if(atom(p->a))
-			temlis.a = cons(p, temlis.a);
-	prog.go = temlis.a;
-	temlis.a = nil;
-	alist[nargs++] = prog.go;
-
 	/* execute */
 	prog.ret = nil;
 	while(prog.pc != nil){
 		p = prog.pc->a;
 		prog.pc = prog.pc->d;
-		progstmt(&prog, p);
+		if(!atom(p))
+			eval(p, a);
 	}
 
-	return prog.ret;
+	p = prog.ret;
+	prog = progsv;
+	return p;
 }
 
 void
@@ -1156,6 +1103,8 @@
 	FSUBR("AND", and_fsubr)
 	FSUBR("OR", or_fsubr)
 	FSUBR("PROG", prog_fsubr)
+	FSUBR("RETURN", return_fsubr)
+	FSUBR("GO", go_fsubr)
 
 	FSUBR("SETQ", setq_fsubr)
 	FSUBR("SET", set_fsubr)