48
48
//
49
49
// slight increase if change the MAX_ALLOC to 512 but it keeps 17K free! => 4180ms
50
50
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
+
51
63
// 20151121: (time (fibo 24)) (5170 . xxx)
52
64
//
53
65
// (fibo 24)
@@ -982,6 +994,8 @@ PRIM evallist(lisp e, lisp* envp) {
982
994
return r ;
983
995
}
984
996
997
+ static inline int tracep (lisp f );
998
+
985
999
// dummy function that doesn't eval, used instead of eval
986
1000
static PRIM noEval (lisp x , lisp * envp ) { return x ; }
987
1001
@@ -1100,7 +1114,6 @@ static inline lisp mkimmediate(lisp e, lisp env) {
1100
1114
return (lisp )r ;
1101
1115
}
1102
1116
1103
-
1104
1117
// these are formed by evaluating a lambda
1105
1118
PRIM mkfunc (lisp e , lisp env ) {
1106
1119
func * r = ALLOC (func );
@@ -1310,30 +1323,61 @@ PRIM equal(lisp a, lisp b) {
1310
1323
return cmp (a , b ) ? nil : t ;
1311
1324
}
1312
1325
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 ; }
1316
1330
1317
1331
inline lisp getBind (lisp * envp , lisp name , int create ) {
1318
1332
//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
1319
1335
if (create && envp == global_envp ) return hashsym (name , NULL , 0 , create );
1320
- if (create ) return nil ;
1336
+ // if (create) return nil;
1321
1337
1338
+ // first search local lexical env
1322
1339
lisp bind = assoc (name , * envp );
1323
1340
if (bind ) return bind ;
1324
1341
1325
- // check " global"
1342
+ // second search global env (stored in a hashtable)
1326
1343
return hashsym (name , NULL , 0 , 0 ); // not create, read only
1327
1344
}
1345
+ // magic, this "instantiates" an inline function!
1328
1346
lisp getBind (lisp * envp , lisp name , int create );
1329
1347
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
+
1330
1372
// like setqq but returns binding, used by setXX
1331
1373
// 1. define, de - create binding in current environment
1332
1374
// 2. set! only modify existing binding otherwise give error
1333
1375
// 3. setq ??? (allow to define?)
1334
1376
inline lisp _setqqbind (lisp * envp , lisp name , lisp v , int create ) {
1335
1377
lisp bind = getBind (envp , name , create );
1378
+ printf ("SETQBIND: found " ); princ (name ); putchar (' ' ); princ (bind ); terpri ();
1336
1379
if (!bind ) {
1380
+ printf ("SETQBIND: " ); princ (name ); putchar (' ' ); princ (bind ); terpri ();
1337
1381
bind = cons (name , nil );
1338
1382
* envp = cons (bind , * envp );
1339
1383
}
@@ -2052,7 +2096,7 @@ static inline lisp eval_hlp(lisp e, lisp* envp) {
2052
2096
// maybe must search all list till find null, then can look on symbol :-(
2053
2097
// but that's everytime? actually, not it's a lexical scope!
2054
2098
// 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 ))
2056
2100
setcar (e , f );
2057
2101
}
2058
2102
@@ -2245,13 +2289,6 @@ void print_args(lisp env, lisp f) {
2245
2289
printf (") " );
2246
2290
}
2247
2291
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
-
2255
2292
PRIM evalGC (lisp e , lisp * envp ) {
2256
2293
if (!e ) return e ;
2257
2294
char tag = TAG (e );
@@ -2393,15 +2430,15 @@ PRIM let_star(lisp* envp, lisp all) {
2393
2430
static inline lisp bindList (lisp fargs , lisp args , lisp env ) {
2394
2431
// TODO: not recurse!
2395
2432
if (!fargs ) return env ;
2396
- if (symbolp ( fargs )) return cons (cons (fargs , args ), env );
2433
+ if (SYMP ( args )) return cons (cons (fargs , args ), env );
2397
2434
lisp b = cons (car (fargs ), car (args ));
2398
2435
// self tail recursion is "goto" - efficient
2399
2436
return bindList (cdr (fargs ), cdr (args ), cons (b , env ));
2400
2437
}
2401
2438
2402
2439
static inline lisp bindEvalList (lisp fargs , lisp args , lisp * envp , lisp extend ) {
2403
2440
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 );
2405
2442
// This eval cannot be allowed to GC! (since it's part of building a cons structure
2406
2443
// TODO: protect ala evallist
2407
2444
lisp b = cons (car (fargs ), eval (car (args ), envp ));
@@ -2427,8 +2464,9 @@ static inline lisp letevallist(lisp args, lisp* envp, lisp extend) {
2427
2464
static inline lisp letstarevallist (lisp args , lisp * envp , lisp extend ) {
2428
2465
while (args ) {
2429
2466
lisp one = car (args );
2430
- lisp r = eval (car (cdr (one )), & extend );
2431
2467
// 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 );
2432
2470
extend = cons (cons (car (one ), r ), extend );
2433
2471
args = cdr (args );
2434
2472
}
@@ -2461,7 +2499,6 @@ static inline lisp funcapply(lisp f, lisp args, lisp* envp, int noeval) {
2461
2499
return r ;
2462
2500
}
2463
2501
2464
- // TODO: evals it's arguments, shouldn't...
2465
2502
// TODO: prim apply/funcapply may return immediate... (so users should call apply instead)
2466
2503
static inline lisp callfunc (lisp f , lisp args , lisp * envp , lisp e , int noeval ) {
2467
2504
int tag = TAG (f );
@@ -3151,7 +3188,10 @@ lisp lisp_init() {
3151
3188
DEFPRIM (cmp , 2 , cmp_ );
3152
3189
DEFPRIM (equal , 2 , equal );
3153
3190
DEFPRIM (= , 2 , equal );
3154
- DEFPRIM (< , 2 , lessthan );
3191
+ DEFPRIM (< , 2 , lt );
3192
+ DEFPRIM (<=, 2 , lte );
3193
+ DEFPRIM (> , 2 , gt );
3194
+ DEFPRIM (>=, 2 , gte );
3155
3195
3156
3196
// all other <= > >= can be made from cmp
3157
3197
0 commit comments