Skip to content

Commit 0510257

Browse files
committed
- improved speed on trace
- added <= > >=
1 parent 2ad5325 commit 0510257

File tree

4 files changed

+82
-25
lines changed

4 files changed

+82
-25
lines changed

env.lsp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,27 @@
2424
(if (null? L) nil
2525
(append2 (car L) (apply append (cdr L)))))
2626

27+
;; sorting
28+
29+
(de merge (a b cmp)
30+
(cond ((null? a) b)
31+
((null? b) a)
32+
((cmp (car a) (car b)) (cons (car a) (merge (cdr a) b cmp)))
33+
(t (cons (car b) (merge a (cdr b) cmp)))))
34+
35+
(define sort)
36+
37+
(de qsort (a L cmp)
38+
(if (null? L) (cons a)
39+
(append
40+
(sort (filter (lambda (x) (cmp x a)) L) cmp)
41+
(list a)
42+
(sort (filter (lambda (x) (not (cmp x a))) L) cmp))))
43+
44+
(de sort (L f)
45+
(if (null? L) nil
46+
(qsort (car L) (cdr L) (or f <))))
47+
2748
;; tracing functions
2849

2950
(define *TR)
@@ -34,3 +55,4 @@
3455
(de untrace (f)
3556
(if (func? f) (untrace (funame f))
3657
(set! *TR (filter (lambda (x) (not (eq f x))) *TR))))
58+

lisp.c

Lines changed: 59 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,18 @@
4848
//
4949
// slight increase if change the MAX_ALLOC to 512 but it keeps 17K free! => 4180ms
5050

51+
// We've slowed down some with adding the evallist/plus/times
52+
// and trace functionality:
53+
// > git checkout f871de73834340edb3fa5b26d49e43e373647f9b
54+
// ./opt
55+
// lisp> (time (fibo 34))
56+
// 3 times, avg = 7015
57+
// NOW
58+
// ./opt
59+
// lisp> (time (fibo 34))
60+
// 3 times, avg = 7671
61+
62+
5163
// 20151121: (time (fibo 24)) (5170 . xxx)
5264
//
5365
// (fibo 24)
@@ -982,6 +994,8 @@ PRIM evallist(lisp e, lisp* envp) {
982994
return r;
983995
}
984996

997+
static inline int tracep(lisp f);
998+
985999
// dummy function that doesn't eval, used instead of eval
9861000
static PRIM noEval(lisp x, lisp* envp) { return x; }
9871001

@@ -1100,7 +1114,6 @@ static inline lisp mkimmediate(lisp e, lisp env) {
11001114
return (lisp)r;
11011115
}
11021116

1103-
11041117
// these are formed by evaluating a lambda
11051118
PRIM mkfunc(lisp e, lisp env) {
11061119
func* r = ALLOC(func);
@@ -1310,30 +1323,61 @@ PRIM equal(lisp a, lisp b) {
13101323
return cmp(a, b) ? nil : t;
13111324
}
13121325

1313-
PRIM lessthan(lisp a, lisp b) {
1314-
return cmp(a, b) < 0 ? t : nil;
1315-
}
1326+
PRIM lt (lisp a, lisp b) { return cmp(a, b) < 0 ? t : nil; }
1327+
PRIM lte(lisp a, lisp b) { return cmp(a, b) <= 0 ? t : nil; }
1328+
PRIM gt (lisp a, lisp b) { return cmp(a, b) > 0 ? t : nil; }
1329+
PRIM gte(lisp a, lisp b) { return cmp(a, b) >= 0 ? t : nil; }
13161330

13171331
inline lisp getBind(lisp* envp, lisp name, int create) {
13181332
//printf("GETBIND: envp=%u global_envp=%u ", (unsigned int)envp, (unsigned int)global_envp); princ(name); terpri();
1333+
1334+
// if we're at top level create a global binding and entry in the hashtable
13191335
if (create && envp == global_envp) return hashsym(name, NULL, 0, create);
1320-
if (create) return nil;
1336+
// if (create) return nil;
13211337

1338+
// first search local lexical env
13221339
lisp bind = assoc(name, *envp);
13231340
if (bind) return bind;
13241341

1325-
// check "global"
1342+
// second search global env (stored in a hashtable)
13261343
return hashsym(name, NULL, 0, 0); // not create, read only
13271344
}
1345+
// magic, this "instantiates" an inline function!
13281346
lisp getBind(lisp* envp, lisp name, int create);
13291347

1348+
// TODO: measure overhead! (compare to: f871de73834340edb3fa5b26d49e43e373647f9b)
1349+
// (time (fibo 34))
1350+
// - before: 6973
1351+
// - after but nothing in list: 7729
1352+
// - 3 items check make it 600 ms slower
1353+
// - 6 items -> 1300 ms slower...
1354+
//
1355+
// - this function adds maybe 10% overhead
1356+
// - if function return 0 directly still 5% overhead
1357+
// ==> other sourced of changes that slowed down... (like evallist)
1358+
static inline int tracep(lisp f) {
1359+
static lisp vb = 0;
1360+
if (!vb && global_envp) vb = getBind(global_envp, symbol("*TR"), 0);
1361+
lisp x = cdr(vb);
1362+
if (!vb || !x) return 0;
1363+
lisp fn = funame(f);
1364+
// inlined member 3 items 3000 ms overhead -> 600 ms!
1365+
while (x) {
1366+
if (fn == car(x)) return 1;
1367+
x = cdr(x);
1368+
}
1369+
return 0;
1370+
}
1371+
13301372
// like setqq but returns binding, used by setXX
13311373
// 1. define, de - create binding in current environment
13321374
// 2. set! only modify existing binding otherwise give error
13331375
// 3. setq ??? (allow to define?)
13341376
inline lisp _setqqbind(lisp* envp, lisp name, lisp v, int create) {
13351377
lisp bind = getBind(envp, name, create);
1378+
printf("SETQBIND: found "); princ(name); putchar(' '); princ(bind); terpri();
13361379
if (!bind) {
1380+
printf("SETQBIND: "); princ(name); putchar(' '); princ(bind); terpri();
13371381
bind = cons(name, nil);
13381382
*envp = cons(bind, *envp);
13391383
}
@@ -2052,7 +2096,7 @@ static inline lisp eval_hlp(lisp e, lisp* envp) {
20522096
// maybe must search all list till find null, then can look on symbol :-(
20532097
// but that's everytime? actually, not it's a lexical scope!
20542098
// TODO: only replace if not found in ENV and is on an SYMBOL!
2055-
if (symbolp(orig) && eq(funame(f), orig))
2099+
if (SYMP(orig) && eq(funame(f), orig))
20562100
setcar(e, f);
20572101
}
20582102

@@ -2245,13 +2289,6 @@ void print_args(lisp env, lisp f) {
22452289
printf(") ");
22462290
}
22472291

2248-
// TODO: measure overhead!
2249-
int tracep(lisp f) {
2250-
static lisp vb = 0;
2251-
if (!vb && global_envp) vb = getBind(global_envp, symbol("*TR"), 0);
2252-
return vb && cdr(vb) && member(funame(f), cdr(vb));
2253-
}
2254-
22552292
PRIM evalGC(lisp e, lisp* envp) {
22562293
if (!e) return e;
22572294
char tag = TAG(e);
@@ -2393,15 +2430,15 @@ PRIM let_star(lisp* envp, lisp all) {
23932430
static inline lisp bindList(lisp fargs, lisp args, lisp env) {
23942431
// TODO: not recurse!
23952432
if (!fargs) return env;
2396-
if (symbolp(fargs)) return cons(cons(fargs, args), env);
2433+
if (SYMP(args)) return cons(cons(fargs, args), env);
23972434
lisp b = cons(car(fargs), car(args));
23982435
// self tail recursion is "goto" - efficient
23992436
return bindList(cdr(fargs), cdr(args), cons(b, env));
24002437
}
24012438

24022439
static inline lisp bindEvalList(lisp fargs, lisp args, lisp* envp, lisp extend) {
24032440
while (fargs) {
2404-
if (symbolp(fargs)) return cons(cons(fargs, evallist(args, envp)), extend);
2441+
if (SYMP(fargs)) return cons(cons(fargs, evallist(args, envp)), extend);
24052442
// This eval cannot be allowed to GC! (since it's part of building a cons structure
24062443
// TODO: protect ala evallist
24072444
lisp b = cons(car(fargs), eval(car(args), envp));
@@ -2427,8 +2464,9 @@ static inline lisp letevallist(lisp args, lisp* envp, lisp extend) {
24272464
static inline lisp letstarevallist(lisp args, lisp* envp, lisp extend) {
24282465
while (args) {
24292466
lisp one = car(args);
2430-
lisp r = eval(car(cdr(one)), &extend);
24312467
// This eval cannot be allowed to GC! (since it's part of building a cons structure
2468+
// TODO: protect ala evallist
2469+
lisp r = eval(car(cdr(one)), &extend);
24322470
extend = cons(cons(car(one), r), extend);
24332471
args = cdr(args);
24342472
}
@@ -2461,7 +2499,6 @@ static inline lisp funcapply(lisp f, lisp args, lisp* envp, int noeval) {
24612499
return r;
24622500
}
24632501

2464-
// TODO: evals it's arguments, shouldn't...
24652502
// TODO: prim apply/funcapply may return immediate... (so users should call apply instead)
24662503
static inline lisp callfunc(lisp f, lisp args, lisp* envp, lisp e, int noeval) {
24672504
int tag = TAG(f);
@@ -3151,7 +3188,10 @@ lisp lisp_init() {
31513188
DEFPRIM(cmp, 2, cmp_);
31523189
DEFPRIM(equal, 2, equal);
31533190
DEFPRIM(=, 2, equal);
3154-
DEFPRIM(<, 2, lessthan);
3191+
DEFPRIM(<, 2, lt);
3192+
DEFPRIM(<=, 2, lte);
3193+
DEFPRIM(>, 2, gt);
3194+
DEFPRIM(>=, 2, gte);
31553195

31563196
// all other <= > >= can be made from cmp
31573197

lisp.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ typedef struct {
3434
#define GETCONS(x) ((conss*)(((unsigned int)x) & ~2))
3535
#define MKCONS(x) ((lisp)(((unsigned int)x) | 2))
3636

37-
#define SYMP(x) ((((unsigned int)x) & 3) == 3)
37+
#define SYMP(x) ((((unsigned int)x) & 3) == 3) // true for HSYMP too!
3838
#define HSYMP(x) ((((unsigned int)x) & 0xff) == 0xff)
3939

4040
lisp mkprim(char* name, int n, void *f);

scheme.lsp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,5 @@
11
;; Scheme compatibly layer
22

3-
; math functions
4-
(de <= (a b) (< (cmp a b) 1)
5-
(de > (a b) (< (cmp b a) 0)
6-
(de >= (a b) (< (cmp b a) 1)
7-
83
; string functions
94
(define string< <)
105
(define string> >)

0 commit comments

Comments
 (0)