UNPKG

algebrite

Version:

Computer Algebra System in Coffeescript

81 lines (66 loc) 2.1 kB
# Store a function definition # # Example: # # f(x,y)=x^y # # For this definition, p1 points to the following structure. # # p1 # | # ___v__ ______ ______ # |CONS |->|CONS |--------------------->|CONS | # |______| |______| |______| # | | | # ___v__ ___v__ ______ ______ ___v__ ______ ______ # |SETQ | |CONS |->|CONS |->|CONS | |CONS |->|CONS |->|CONS | # |______| |______| |______| |______| |______| |______| |______| # | | | | | | # ___v__ ___v__ ___v__ ___v__ ___v__ ___v__ # |SYM f | |SYM x | |SYM y | |POWER | |SYM x | |SYM y | # |______| |______| |______| |______| |______| |______| # # the result (in f) is a FUNCTION node # that contains both the body and the argument list. # # We have # # caadr(p1) points to the function name i.e. f # cdadr(p1) points to the arguments i.e. the list (x y) # caddr(p1) points to the function body i.e. (power x y) #define F p3 # F points to the function name #define A p4 # A points to the argument list #define B p5 # B points to the function body define_user_function = -> p3 = caadr(p1); # p3 is F p4 = cdadr(p1); # p4 is A p5 = caddr(p1); # p5 is B if (!issymbol(p3)) # p3 is F stop("function name?") # evaluate function body (maybe) if (car(p5) == symbol(EVAL)) # p5 is B push(cadr(p5)); # p5 is B Eval() p5 = pop(); # p5 is B # note how, unless explicitly forced by an eval, # (handled by the if just above) # we don't eval/simplify # the body. # Why? because it's the easiest way # to solve scope problems i.e. # x = 0 # f(x) = x + 1 # f(4) # would reply 1 # which would need to otherwise # be solved by some scope device # somehow push_symbol(FUNCTION) push p5 push p4 list(3) p5 = pop() set_binding(p3, p5); # p3 is F (function name) # p4 is A # p5 is B # return value is nil push_symbol(NIL) Eval_function_reference = -> push p1