http://GameProgrammer.Com

Programming

GP Mailing List
     Thread Index
     Date Index

ATXGPSIG List
     Thread Index
     Date Index

Google
>

Home

Wise2Food



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[gameprogrammer] Re: Scripting engines: Upvalues and function refs



On Fri, 2004-04-02 at 03:30, David Olofson wrote:
> Dunno if this is the best list for this question, but I guess some 
> people around here have some experience with implementing scripting 
> engines. (And either way, if this gets through, it means I'm still on 
> the new list. ;-)
> 
> Anyway, here goes:
> 
> I'm hacking a new version of EEL; the scripting engine used in 
> Audiality. (A major rewrite. This one's using a mostly RT safe 
> virtual machine instead of executing from the source.)
> 
> 	A. I have local functions with upvalues. (Full
> 	   lexical scoping, implemented by backtracing
> 	   the call stack.)
> 
> 	B. The top level of a source file (module) is
> 	   compiled as a top level functions, so any
> 	   "top level" functions are actually local
> 	   functions to that module.
> 
> 	C. The language supports only dynamically typed
> 	   variables at this point. (Statically typed
> 	   variables on the TODO, for performance and
> 	   improved compile time error checking.)
> 
> 	D. Function calls can be either "hardwired" at
> 	   compile time, or called through references.
>  
> 
> Now, if you consider the above, you'll probably realize that this 
> causes some problems:
> 
> 	1. When calling via references, you have no clue
> 	   what you're calling at compile time. (Not a
> 	   major issue in itself, though the run time
> 	   checking will impact performance a bit.)
> 
> 	2. All directly callable functions are actually
> 	   local functions, and may try to use upvalues.
> 	   What looks like global variables in a module
> 	   are actually locals of the top level function,
> 	   and "normal" functions access them as upvalues.
> 
> 	3. You can't easilly tell what register frame to
> 	   pass as "upvalue frame" to a function.
> 
> 	4. You may end up violating the scoping rules,
> 	   trying to call functions that are not callable
> 	   from the current context. (Even if you grab
> 	   the function reference when the function has
> 	   a valid context, that context may no longer
> 	   exist when someone decides to call via that
> 	   reference!)
> 
> 
> I'm thinking about not allowing getting references to functions using 
> upvalues. That may seem like an obvious and logical restriction, but 
> note that this prevents you from calling functions that use "globals" 
> on the module level via references...
> 
> Another solution is to make top level functions and global variables 
> of modules special; more like in C, C++ and (Object) Pascal. I don't 
> quite like it, though. I want the scoping rules to be complemely 
> conistent, so you can do *anything* in any scope, within reasonable 
> limits. (Local functions, local classes etc...)
> 
> It would be kinda' kewl if I could just make it impossible to pass 
> references to local functions to contexts that cannot call them, but 
> I can't quite see how to do that in a logical and comprehensible way, 
> since any dynamically typed variable or argument can hold a function 
> reference... (That is, I can't prevent illegal reference passing by 
> restricting the scope of the reference type, or something like that.)
> 
> 
> Any ideas? How do other languages with upvalues handle function 
> pointers/references?

I assume that by an "upvalue" you mean a value defined in an outer
scope? If so then the solution to the problem is to not delete contexts
until you are actually done with them. If some one has a reference to a
function, and the function is in a context, then you can't delete the
context until the reference to the function is deleted.

The easiest way to do that involves adding a garbage collector of some
sort and it requires that contexts are savable. When you get a reference
to a function you actually get a pair with a reference to the context
and a reference to the function. When you call the reference you
instantiate the context and call the function.

Take a look at continuations in Scheme for an example of a language that
does something like what I just described. Also, try to find a copy of,
Moses, Joel (1970) "The function of FUNCTION in LISP or why the FUNARG
problem should be called the environment problem", M.I.T. Artificial
Intelligence Memo 199, Cambridge, Mass. 

> 
> 
> //David Olofson - Programmer, Composer, Open Source Advocate
> 
> .- Audiality -----------------------------------------------.
> |  Free/Open Source audio engine for games and multimedia.  |
> | MIDI, modular synthesis, real time effects, scripting,... |
> `-----------------------------------> http://audiality.org -'
>    --- http://olofson.net --- http://www.reologica.se ---
> 
-- 
+---------------------------------------+
+ Bob Pendleton: writer and programmer. +
+ email: Bob@Pendleton.com              +
+ web:   www.GameProgrammer.com         +
+---------------------------------------+