Skip to content

Commit 22e2415

Browse files
authored
Merge pull request #439 from jscl-project/fix-funcall-error-message
Ensure unboundFunction is bound to the right symbol
2 parents 29885f7 + 9e126ca commit 22e2415

File tree

5 files changed

+28
-9
lines changed

5 files changed

+28
-9
lines changed

src/boot.lisp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,9 @@
156156
(boundp x))
157157

158158
(defun fboundp (x)
159-
(fboundp x))
159+
(if (functionp x)
160+
(error "FBOUNDP - invalid function name ~a." x))
161+
(%fboundp x))
160162

161163
(defun eq (x y) (eq x y))
162164
(defun eql (x y) (eq x y))

src/compiler/compiler.lisp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1220,8 +1220,8 @@
12201220
(define-builtin boundp (x)
12211221
(convert-to-bool `(!== (get ,x "value") undefined)))
12221222

1223-
(define-builtin fboundp (x)
1224-
(convert-to-bool `(!== (get ,x "fvalue") (internal |unboundFunction|))))
1223+
(define-builtin %fboundp (x)
1224+
(convert-to-bool `(call-internal |fboundp| ,x)))
12251225

12261226
(define-builtin symbol-value (x)
12271227
`(call-internal |symbolValue| ,x))

src/prelude.js

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ internals.forcemv = function(x) {
5959
return typeof x == 'object' && x !== null && 'multiple-value' in x? x: internals.mv(x);
6060
};
6161

62-
6362
//
6463
// Workaround the problems with `new` for arbitrary number of
6564
// arguments. Some primitive constructors (like Date) differ if they
@@ -331,15 +330,21 @@ packages.KEYWORD = {
331330

332331
jscl.CL = packages.CL.exports;
333332

334-
internals.unboundFunction = function () {
335-
throw new Error("Function '" + this.name + "' undefined");
333+
334+
335+
const UNBOUND = Symbol('UnboundFunction')
336+
337+
internals.makeUnboundFunction = function (symbol) {
338+
const fn = ()=>{ throw new Error("Function '" + symbol.name + "' undefined");}
339+
fn[UNBOUND] = true;
340+
return fn;
336341
};
337342

338343
internals.Symbol = function(name, package_name){
339344
this.name = name;
340345
this.package = package_name;
341346
this.value = undefined;
342-
this.fvalue = internals.unboundFunction;
347+
this.fvalue = internals.makeUnboundFunction(this)
343348
this.stack = [];
344349
};
345350

@@ -352,9 +357,17 @@ internals.symbolValue = function (symbol){
352357
}
353358
};
354359

360+
internals.fboundp = function (symbol) {
361+
if (symbol instanceof internals.Symbol){
362+
return !symbol.fvalue[UNBOUND]
363+
} else {
364+
throw new Error(`${symbol} is not a symbol`)
365+
}
366+
}
367+
355368
internals.symbolFunction = function (symbol){
356369
var fn = symbol.fvalue;
357-
if (fn === internals.unboundFunction)
370+
if (fn[UNBOUND])
358371
symbol.fvalue();
359372
return fn;
360373
};

tests/defstruct.lisp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@
113113
(test
114114
(mv-eql
115115
(values
116-
(mapcar 'fboundp (list #'sbt-02-a #'sbt-02-p #'copy-sbt-02))
116+
(mapcar 'fboundp (list 'sbt-02-a 'sbt-02-p 'copy-sbt-02))
117117
(sbt-02-con)
118118
(sbt-02-con :foo 99)
119119
(sbt-02-a (sbt-02-con :foo 1234)))

tests/variables.lisp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,8 @@
2222
(let ((*special-defparameter* 2))
2323
(test (= (f) 2))))
2424

25+
26+
(test (not (fboundp 'abc)))
27+
28+
2529
;;; EOF

0 commit comments

Comments
 (0)