;; This is a temporary test file, move everything to a test suite and/or docs once it works! ; ;test code: ;(let ((x (apply length '((#t #f)))) ; (y (apply length '((#t #f))))) ;(if (apply length '((#t #f))) ; 2 ; #f)) (write (cons (apply cons '(1 2)) (apply cons '(3 4)))) ;; The purpose of this file is to test interactions between the interpreter ;; and compiled code. ;; ;; Some requirements and notes: ;; - The interpreter can create new variables, but those new vars are only ;; accessible by the interpreter (otherwise code would not compile) ;; - The interpreter should be able to access compiled variables, including ;; functions ;; - The interpreter should be able to call compiled functions ;; - The interpreter should be able to change variables that originate ;; in compiled code ;; - If eval is never called, compiled code can be more efficient by omitting ;; information that is only required by the interpreter. ;; ;; How to represent environments? ;; Presumably the interpreter's global environment needs to include compiled globals as well. It should also be extended to include local vars, presumably prior to each call to eval?? ;; ;; global env can be extended to include C globals and locals. their representations will be: ;; ;; - globals are just C variables. problem is, we may need to include the locations of those vars. otherwise how can the interpreter mutate them? IE, if global 'x' is a list, need the memory location of 'x' not the list, if we want to mutate the list ;; simple - add a new type for globals that includes the memory address, ;; but whenever we look one up, return the obj at that address. ;; we want to avoid 'leaking' global objs outside of the env and associated ;; code. then when a set comes in, change the var at the memory address. ;; ;; obviously we want to just load the globals once when *global-env* is ;; built, and do not want to load them ever again. ;; ;; does any of this apply to locals? ;; ;; - locals are ... ? cells? ;; presumably we need to extend global-env to include locals, then pass that ;; extended env as the parameter to eval, each time it is called. ;; this obviously would happen in the compiled code generated by cyclone. ;; ;; local can be a local C variable: ;; ((lambda (x) (display x)) 1) ;; ... ;; static void __lambda_11(int argc, closure _,object x_737) { ;; return_check1(__lambda_10,Cyc_display(x_737));; ;; } ;; but it can also be a closure: ;; ((lambda (x) ;; ((lambda () (display x)))) ;; 1) ;; ... ;; static void __lambda_12(int argc, closure _,object x_737) { ;; ;; closureN_type c_7380; ;; c_7380.tag = closureN_tag; ;; c_7380.fn = __lambda_11; ;; c_7380.num_elt = 1; ;; c_7380.elts = (object *)alloca(sizeof(object) * 1); ;; c_7380.elts[0] = x_737; ;; ;; return_funcall0((closure)&c_7380);; ;; } ;; ;; static void __lambda_11(int argc, object self_7331) { ;; return_check1(__lambda_10,Cyc_display(((closureN)self_7331)->elts[0]));; ;; } ;; ;; case #1 - pass a global variable to the interpreter (define x 1) (define y 2) (define *z* 3) ;(write (eval '(Cyc-global-vars))) (write (eval 'x)) (write (eval '(set! x 'mutated-x))) ;(write (eval '*global-environment*)) (write (eval '*z*)) ; TODO: need a valid example of passing a local to eval (assume that is allowed) ;((lambda (tmp) ; (write (eval 'tmp))) #f) (write (list 'after-eval 'x x 'y y '*z* *z*)) x ;; oh shit, need to reference x/y otherwise they get optimized out! ;; case #2 - pass a local (IE, lambda var) ;; No, this is not allowed, see: http://stackoverflow.com/questions/3844196/how-can-i-use-external-variables-in-eval-in-scheme/3851284#3851284 ;; case #3 - mutate global/local. or is this the same as previous? ;; case #4 - introduce new vars in interpreter, then use them later on??