MAXScript Compiler and Interpreter
The MAXScript engine executes MAXScript code using the following steps:
- First a
Parser
object (found inmaxscrpt
\parser.h) is instantiated with an output stream (i.e. aCharStream
object foundmaxscrpt
\streams.h) for debugging and error output. - Next the
Parser::Compile
(CharStream*) method is called, which will return an expression that can be executed represented as aValue
*. This might beCodeTree
instance, but could also be a simple literal. - The method
Value::eval()
is then called to theCodeTree
instance or do nothing if theValue
is a literal..
The following code snippet (from maxsdk\howto\maxscript\testdlx\tester.cpp) demonstrates these steps:
static Value* file_in(CharStream* source, MAXScript::ScriptSource scriptSource, int quiet)
{
ScopedMaxScriptEvaluationContext scopedMaxScriptEvaluationContext;
MAXScript_TLS* _tls = scopedMaxScriptEvaluationContext.Get_TLS();
three_typed_value_locals_tls(Parser* parser, Value* code, Value* result);
CharStream* out = _tls->current_stdout;
if (!quiet)
source->log_to(out);
save_current_source_tls();
MacroRecorder::MacroRecorderDisable macroRecorderDisable;
// loop through stream compiling & evaluating all expressions
try
{
// make a new compiler instance
vl.parser = new Parser (out);
source->flush_whitespace();
while (!source->at_eos() || vl.parser->back_tracked)
{
vl.code = vl.parser->compile(source, scriptSource);
vl.result = vl.code->eval();
if (!quiet)
vl.result->print();
source->flush_whitespace();
}
if (vl.parser->expr_level != 0 || vl.parser->back_tracked && vl.parser->token != t_end)
throw RuntimeError (MaxSDK::GetResourceStringAsMSTR(IDS_UNEXPECTED_END_OF_FILE_DURING_FILEIN));
source->close();
}
catch (...)
{
// catch any errors and tell what file we are in if any
out->puts(_T("Error occurred during fileIn: "));
source->sprin1(out);
out->puts(_T("\n"));
source->close();
restore_current_source_tls();
throw;
}
restore_current_source_tls();
// if there was one, return last expression in stream as result
if (vl.result == NULL)
vl.result = &ok;
else
vl.result = vl.result->get_heap_ptr();
return_value_tls(vl.result);
}