summaryrefslogtreecommitdiffstats
path: root/share/txr/stdlib/param.tl
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2021-03-27 14:26:40 -0700
committerKaz Kylheku <kaz@kylheku.com>2021-03-27 14:26:40 -0700
commit641c0f421cdb70d410df1e28d34c29e6dd536512 (patch)
tree7a05fffba23755c057e6f3befe49093c5a86bd1e /share/txr/stdlib/param.tl
parenta7880f77c8732c589c410b3294bd09abe6419f1f (diff)
downloadtxr-641c0f421cdb70d410df1e28d34c29e6dd536512.tar.gz
txr-641c0f421cdb70d410df1e28d34c29e6dd536512.tar.bz2
txr-641c0f421cdb70d410df1e28d34c29e6dd536512.zip
compiler: check number of arguments.
We implement rudimentary compile-time checking beween function calls and function definitions. * share/txr/stdlib/compiler.tl (dstruct frag): We add one more optional BOA parameter, corresponding to a new slot. This is used when compiling a lambda. A lambda fragment is annotated with the parameter parser object which gives information about its arguments. (struct fbinding): New slot, pars. When processing a sys:fbind or sys:lbind form, we decorate the lexical function bindings with the parameter object pulled from the lambda fragment that is compiled for each function binding. (*unchecked-calls*): New special variable. This is used for checking, at the end of the compilation unit, the arguments of calls to functions that were not defined at the time of the call. (compiler comp-fbind): When processing the lambda expressions, propagate the parameter object from the compiled lambda fragment to the function binding. (compiler comp-fun-form): On entry, look up the function being called and if it is lexical or has a global definition, check the arguments. If it has no definition, push information into the *unchecked-calls* list to do the check later, if possible. Also, there is a behavior change here now: optimizations are now applied here only to functions that don't have a lexical binding. Thus if the application lexically redefines a standard function, and calls it, we won't try to optimize it. (param-check): New function. * share/txr/stdlib/param.tl (param-info): New struct. This presents information about a global function in a similar way to param-parser, using some of the same fields. With this object we can check the call to a lexical function or global function in a uniform way, using the same code.
Diffstat (limited to 'share/txr/stdlib/param.tl')
-rw-r--r--share/txr/stdlib/param.tl16
1 files changed, 15 insertions, 1 deletions
diff --git a/share/txr/stdlib/param.tl b/share/txr/stdlib/param.tl
index 5f3c1b42..c04325c9 100644
--- a/share/txr/stdlib/param.tl
+++ b/share/txr/stdlib/param.tl
@@ -67,4 +67,18 @@
(mac-param-p nil))
(defstruct (mac-param-parser syntax form) param-parser-base
- (mac-param-p t)))
+ (mac-param-p t))
+
+ (defstruct (param-info symbol) nil
+ symbol
+ nreq nopt nfix rest
+ (:postinit (me)
+ (let* ((fun (or (symbol-function me.symbol)
+ (error "~s: no such function: ~s"
+ 'param-info me.symbol)))
+ (fix (fun-fixparam-count fun))
+ (opt (fun-optparam-count fun)))
+ (set me.nreq (- fix opt)
+ me.nopt opt
+ me.nfix fix
+ me.rest (fun-variadic fun))))))