@@ -40,6 +40,7 @@ func init() {
40
40
ops ["dotimes" ] = makeFn (FtSpecial , doDotimes )
41
41
ops ["prin1" ] = makeFn (FtBuiltin , doPrin1 )
42
42
ops ["print" ] = makeFn (FtBuiltin , doPrint )
43
+ ops ["princ" ] = makeFn (FtBuiltin , doPrinc )
43
44
ops ["let" ] = makeFn (FtSpecial , doLet )
44
45
ops ["let*" ] = makeFn (FtSpecial , doLetStar )
45
46
ops ["setq" ] = makeFn (FtSpecial , doSetq )
@@ -68,6 +69,8 @@ func init() {
68
69
ops ["apply" ] = makeFn (FtBuiltin , doApply )
69
70
ops ["concatenate" ] = makeFn (FtBuiltin , doConcatenate )
70
71
ops ["defun" ] = makeFn (FtSpecial , doDefun )
72
+ ops ["float" ] = makeFn (FtBuiltin , doFloat )
73
+ ops ["while" ] = makeFn (FtSpecial , doWhile )
71
74
ops ["quote" ] = makeFn (FtSpecial , doQuote )
72
75
ops ["getenv" ] = makeFn (FtBuiltin , doGetenv )
73
76
ops ["length" ] = makeFn (FtBuiltin , doLength )
@@ -411,7 +414,7 @@ func doPrin1(env *Env, node *Node) (*Node, error) {
411
414
if node .car .t == NodeNil {
412
415
fmt .Fprint (env .out , "nil" )
413
416
} else {
414
- fmt .Fprint (env .out , node .car .v )
417
+ fmt .Fprintln (env .out , node .car .v )
415
418
}
416
419
return node .car , nil
417
420
}
@@ -434,6 +437,24 @@ func doPrint(env *Env, node *Node) (*Node, error) {
434
437
return node .car , nil
435
438
}
436
439
440
+ func doPrinc (env * Env , node * Node ) (* Node , error ) {
441
+ if node .car == nil {
442
+ return nil , errors .New ("invalid arguments for print" )
443
+ }
444
+ if node .car .t == NodeNil {
445
+ fmt .Fprint (env .out , "nil" )
446
+ } else if node .car .t == NodeT {
447
+ fmt .Fprint (env .out , "t" )
448
+ } else if node .car .t == NodeQuote {
449
+ fmt .Fprint (env .out , node .car )
450
+ } else if node .car .t == NodeCell {
451
+ fmt .Fprint (env .out , node .car )
452
+ } else {
453
+ fmt .Fprint (env .out , node .car .v )
454
+ }
455
+ return node .car , nil
456
+ }
457
+
437
458
func doDotimes (env * Env , node * Node ) (* Node , error ) {
438
459
var err error
439
460
@@ -1390,6 +1411,53 @@ func doConcatenate(env *Env, node *Node) (*Node, error) {
1390
1411
}, nil
1391
1412
}
1392
1413
1414
+ func doFloat (env * Env , node * Node ) (* Node , error ) {
1415
+ if node .car == nil {
1416
+ return nil , errors .New ("invalid arguments for float" )
1417
+ }
1418
+ var ret float64
1419
+ switch node .car .t {
1420
+ case NodeInt :
1421
+ ret = float64 (node .car .v .(int64 ))
1422
+ case NodeDouble :
1423
+ ret = node .car .v .(float64 )
1424
+ default :
1425
+ return nil , errors .New ("invalid arguments for float" )
1426
+ }
1427
+
1428
+ return & Node {
1429
+ t : NodeDouble ,
1430
+ v : ret ,
1431
+ }, nil
1432
+ }
1433
+
1434
+ func doWhile (env * Env , node * Node ) (* Node , error ) {
1435
+ if node .car == nil {
1436
+ return nil , errors .New ("invalid arguments for while" )
1437
+ }
1438
+
1439
+ scope := NewEnv (env )
1440
+
1441
+ for {
1442
+ ret , err := eval (env , node .car )
1443
+ if err != nil {
1444
+ return nil , err
1445
+ }
1446
+ if ret .t != NodeT {
1447
+ break
1448
+ }
1449
+ ret , err = doProgn (scope , node )
1450
+ if err != nil {
1451
+ return nil , err
1452
+ }
1453
+ }
1454
+
1455
+ return & Node {
1456
+ t : NodeNil ,
1457
+ v : nil ,
1458
+ }, nil
1459
+ }
1460
+
1393
1461
func doDefun (env * Env , node * Node ) (* Node , error ) {
1394
1462
v := & Node {
1395
1463
t : NodeEnv ,
0 commit comments