UNPKG

2.1 kBtext/coffeescriptView Raw
1# Store a function definition
2#
3# Example:
4#
5# f(x,y)=x^y
6#
7# For this definition, p1 points to the following structure.
8#
9# p1
10# |
11# ___v__ ______ ______
12# |CONS |->|CONS |--------------------->|CONS |
13# |______| |______| |______|
14# | | |
15# ___v__ ___v__ ______ ______ ___v__ ______ ______
16# |SETQ | |CONS |->|CONS |->|CONS | |CONS |->|CONS |->|CONS |
17# |______| |______| |______| |______| |______| |______| |______|
18# | | | | | |
19# ___v__ ___v__ ___v__ ___v__ ___v__ ___v__
20# |SYM f | |SYM x | |SYM y | |POWER | |SYM x | |SYM y |
21# |______| |______| |______| |______| |______| |______|
22#
23# the result (in f) is a FUNCTION node
24# that contains both the body and the argument list.
25#
26# We have
27#
28# caadr(p1) points to the function name i.e. f
29# cdadr(p1) points to the arguments i.e. the list (x y)
30# caddr(p1) points to the function body i.e. (power x y)
31
32
33
34#define F p3 # F points to the function name
35#define A p4 # A points to the argument list
36#define B p5 # B points to the function body
37
38define_user_function = ->
39 p3 = caadr(p1); # p3 is F
40 p4 = cdadr(p1); # p4 is A
41 p5 = caddr(p1); # p5 is B
42
43 if (!issymbol(p3)) # p3 is F
44 stop("function name?")
45
46 # evaluate function body (maybe)
47
48 if (car(p5) == symbol(EVAL)) # p5 is B
49 push(cadr(p5)); # p5 is B
50 Eval()
51 p5 = pop(); # p5 is B
52
53 # note how, unless explicitly forced by an eval,
54 # (handled by the if just above)
55 # we don't eval/simplify
56 # the body.
57 # Why? because it's the easiest way
58 # to solve scope problems i.e.
59 # x = 0
60 # f(x) = x + 1
61 # f(4) # would reply 1
62 # which would need to otherwise
63 # be solved by some scope device
64 # somehow
65 push_symbol(FUNCTION)
66 push p5
67 push p4
68 list(3)
69 p5 = pop()
70
71
72 set_binding(p3, p5); # p3 is F (function name) # p4 is A # p5 is B
73
74 # return value is nil
75
76 push_symbol(NIL)
77
78Eval_function_reference = ->
79 push p1
80