395
edits
No edit summary |
Philosopher (talk | contribs) No edit summary |
||
Line 241: | Line 241: | ||
is, but somehow I doubt that in terms of man-hours the effort beats porting the | is, but somehow I doubt that in terms of man-hours the effort beats porting the | ||
existing large-scale Nasal codes to C++. Just my 2 cents in any case. | existing large-scale Nasal codes to C++. Just my 2 cents in any case. | ||
Line 254: | Line 252: | ||
* http://www.mono-project.com/Compacting_GC | * http://www.mono-project.com/Compacting_GC | ||
* http://www.utdallas.edu/~ramakrishnan/Projects/GC_for_C/index.htm | * http://www.utdallas.edu/~ramakrishnan/Projects/GC_for_C/index.htm | ||
= Better debugging/development support = | |||
Besides making a full IDE (which would be ''really'' cool), there are several things that can be done by editing the source code of Nasal to enhance debugging support and increase development : | |||
* Being able to dump the global namespace (see [http://flightgear.org/forums/viewtopic.php?f=30&t=19049&p=182930&#p182930 this topic] for a possible solution) or at least dump things prettily (an unreleased version of the file discussed in [[Nasal Meta-programming]] has good support for nice formatting). | |||
* Register a callback for handling errors using call() | |||
* Register a callback for OP_FCALL et al. to be able to time function calls. Example (relies on the gen.nas module and debug.decompile): | |||
<syntaxhighlight lanh="php"> | |||
# Debugging: | |||
runindebug = func(fn, arg...) { | |||
var start = []; var indent = ""; | |||
call(func, arg, nil, nil, { | |||
op_fcall:func(context) { | |||
var obj = debug.decompile(context.fn); | |||
obj.end = context.ip+1; | |||
append(start, [get_fcall_lvalue(obj)]); | |||
print(indent, "Start function call on function ", start[-1][0]); | |||
append(start[-1], systime()); #save it now for most accurate results | |||
indent ~= " "; | |||
}, | |||
op_return:func { | |||
var v = pop(start); | |||
indent = substr(indent, 0, size(indent)-2); | |||
print(indent, "Took ", systime()-v[1], " seconds"); | |||
}, | |||
error:func(err...) { | |||
printf(err[0]); | |||
for (var i=0; i<size(err); i+=1) | |||
printf(" called from %s line %d", err[i], err[i+=1]); | |||
print("Stack info:"); | |||
var namespace = caller(1)[0]; | |||
printf("Local namespace:"); | |||
printf(" "~gen.dump_namespace(namespace, 0, 2, " ")); | |||
var c = caller(1)[1]; var i = 0; | |||
while ((var cl = closure(c, i)) != nil) { | |||
printf("Closure %d:", i+=1); | |||
printf(" "~gen.dump_namespace(cl, 0, 2, " ")); | |||
} | |||
var stack = debug.stackinfo(); | |||
forindex (var i; stack) { | |||
printf("Caller %d:", i); | |||
printf(" Local namespace:"); | |||
printf(" "~gen.dump_namespace(stack[i].locals, 0, 4, " ")); | |||
} | |||
}, | |||
}, var err=[]); | |||
}; | |||
var get_fcall_lvalue = func(obj, level=0, col=0, suffix="") { | |||
var output = gen.decompile_expr(obj, level, col, suffix); | |||
var level = 1; | |||
for (var i=-2; i>=-size(output) and level > 0; i-=1) { | |||
if (output[i] == `)`) level += 1; | |||
elsif (output[i] == `(`) level -= 1; | |||
} | |||
return substr(output, 0, size(output)-i); | |||
}; | |||
# It is really easy to debug code now, just save off every | |||
# expression to a variable and browse them on error. | |||
var possibly_buggy_code = func(arg...) { | |||
var sum = (var _1 = getprop("/sim/node/not/exists[0]")) + | |||
(var _2 = getprop("/sim/node/not/exists[1]")); | |||
return var _3 = sprintf("%8.7f", sum); | |||
}; | |||
</syntaxhighlight> | |||
* Set breakpoints: not needed (just call a function to do what you want). | |||
* Time other parts of Nasal (not just VM) with a compile-time flag? | |||
* Better error messages – in progress. | |||
** '''Parsing:''' Say something other than "parse error", like "null pointer". | |||
** '''VM:''' Indicate type of variable if wrong type. | |||
** '''Both:''' Could we give line ''and'' column? | |||
* Working with bytecode: | |||
** Expose to Nasal: done | |||
** Decompile to text: partial (untested) | |||
** Optimize: not started | |||
** Working with it: provide Bytecode class: not started | |||
* Inspect Context: not started, should be easy. | |||
* Expose Tokens to Nasal: implemented by Hooray as argument to compile(). | |||
[[Category:Core developer documentation]] | [[Category:Core developer documentation]] |
edits