Open Fuco1 opened 6 years ago
This is all quite easy to do if we adopt a "single-pass" approach, that is we assume all functions are defined before first use.
I'm not sure how to make this a) fast and b) work in multiple passes, such that
(1+ (x 1 2))
(defun x (a b)
(if a (format "%s" (< a b))
(number-to-string b)))
can also understand that the 1+
will error (while x
was not yet defined)
Actually, it is really simple because we can do the read-in of all forms into a list, then iterate the list and analyze.
We can have a routine that would just register the interesting things like defuns/defvars during the read phase and puts the forms in a hash or some such on the state so we can then refer to those and eagerly analyze them out of order if there's an earlier reference.
We should probably still warn that the order should be "declare before use" just to make things consistent.
Assuming types inside functions is actually harmless because the only place where that can break is if we get supplied wrong argument from outside. So in this function
we can safely assume
str
is a string and not generate an error forstring-to-number
taking mixed.However, if we elsewhere
we should report an error there saying 1 is not a string. Similarly we know the function should return a number, so doing
should complain that we are trying to get a name of int instead of a symbol.
The inference could at first be contained completely to the function, it can not do worse than just returning mixed anyway.