mirror of
https://github.com/TorqueGameEngines/Torque3D.git
synced 2026-04-26 23:05:38 +00:00
tscript change
Adds the ability to declare defaults for function arguments
eg
function testFunc(%x = 1, %y = 1)
{
return %x + %y;
}
can now be called as
testFunc(10) and it will return the value of 11.
This commit is contained in:
parent
7e64493dbf
commit
b0f8a5f9bd
8 changed files with 1375 additions and 1206 deletions
|
|
@ -671,10 +671,15 @@ Namespace::Entry::Entry()
|
||||||
mNext = NULL;
|
mNext = NULL;
|
||||||
mPackage = StringTable->EmptyString();
|
mPackage = StringTable->EmptyString();
|
||||||
mToolOnly = false;
|
mToolOnly = false;
|
||||||
|
VECTOR_SET_ASSOCIATION(mArgFlags);
|
||||||
|
VECTOR_SET_ASSOCIATION(mDefaultValues);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Namespace::Entry::clear()
|
void Namespace::Entry::clear()
|
||||||
{
|
{
|
||||||
|
mArgFlags.clear();
|
||||||
|
mDefaultValues.clear();
|
||||||
|
|
||||||
if (mModule)
|
if (mModule)
|
||||||
{
|
{
|
||||||
mModule->decRefCount();
|
mModule->decRefCount();
|
||||||
|
|
|
||||||
|
|
@ -130,6 +130,10 @@ public:
|
||||||
/// The offset in the compiled script code at which this function begins.
|
/// The offset in the compiled script code at which this function begins.
|
||||||
U32 mFunctionOffset;
|
U32 mFunctionOffset;
|
||||||
|
|
||||||
|
// Offsets to get default values for arguments.
|
||||||
|
Vector<U32> mArgFlags;
|
||||||
|
Vector<ConsoleValue> mDefaultValues;
|
||||||
|
|
||||||
/// If it's a script function, this is the line of the declaration in code.
|
/// If it's a script function, this is the line of the declaration in code.
|
||||||
/// @note 0 for functions read from legacy DSOs that have no line number information.
|
/// @note 0 for functions read from legacy DSOs that have no line number information.
|
||||||
U32 mFunctionLineNumber;
|
U32 mFunctionLineNumber;
|
||||||
|
|
|
||||||
|
|
@ -138,6 +138,7 @@ struct Token
|
||||||
%type <slot> slot_acc
|
%type <slot> slot_acc
|
||||||
%type <intslot> intslot_acc
|
%type <intslot> intslot_acc
|
||||||
%type <stmt> expression_stmt
|
%type <stmt> expression_stmt
|
||||||
|
%type <var> param
|
||||||
%type <var> var_list
|
%type <var> var_list
|
||||||
%type <var> var_list_decl
|
%type <var> var_list_decl
|
||||||
%type <asn> assign_op_struct
|
%type <asn> assign_op_struct
|
||||||
|
|
@ -242,12 +243,31 @@ var_list_decl
|
||||||
;
|
;
|
||||||
|
|
||||||
var_list
|
var_list
|
||||||
: VAR
|
: param
|
||||||
{ $$ = VarNode::alloc( $1.lineNumber, $1.value, NULL ); }
|
{ $$ = $1; }
|
||||||
| var_list ',' VAR
|
| var_list ',' param
|
||||||
{ $$ = $1; ((StmtNode*)($1))->append((StmtNode*)VarNode::alloc( $3.lineNumber, $3.value, NULL ) ); }
|
{ $$ = $1; ((StmtNode*)($1))->append((StmtNode*)$3 ); }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
param
|
||||||
|
: VAR
|
||||||
|
{
|
||||||
|
$$ = VarNode::allocParam($1.lineNumber, $1.value, NULL);
|
||||||
|
}
|
||||||
|
| VAR '?'
|
||||||
|
{
|
||||||
|
$$ = VarNode::allocParam($1.lineNumber, $1.value, NULL);
|
||||||
|
}
|
||||||
|
| VAR '=' expr
|
||||||
|
{
|
||||||
|
$$ = VarNode::allocParam($1.lineNumber, $1.value, $3);
|
||||||
|
}
|
||||||
|
| VAR '?' '=' expr
|
||||||
|
{
|
||||||
|
$$ = VarNode::allocParam($1.lineNumber, $1.value, $4);
|
||||||
|
}
|
||||||
|
;
|
||||||
|
|
||||||
datablock_decl
|
datablock_decl
|
||||||
: rwDATABLOCK class_name_expr '(' expr parent_block ')' '{' slot_assign_list_opt '}' ';'
|
: rwDATABLOCK class_name_expr '(' expr parent_block ')' '{' slot_assign_list_opt '}' ';'
|
||||||
{ $$ = ObjectDeclNode::alloc( $1.lineNumber, $2, $4, NULL, $5.value, $8, NULL, true, false, false); }
|
{ $$ = ObjectDeclNode::alloc( $1.lineNumber, $2, $4, NULL, $5.value, $8, NULL, true, false, false); }
|
||||||
|
|
|
||||||
|
|
@ -311,8 +311,13 @@ struct VarNode : ExprNode
|
||||||
StringTableEntry varName;
|
StringTableEntry varName;
|
||||||
ExprNode* arrayIndex;
|
ExprNode* arrayIndex;
|
||||||
|
|
||||||
|
ExprNode* defaultValue; // optional expression
|
||||||
|
|
||||||
static VarNode* alloc(S32 lineNumber, StringTableEntry varName, ExprNode* arrayIndex);
|
static VarNode* alloc(S32 lineNumber, StringTableEntry varName, ExprNode* arrayIndex);
|
||||||
|
|
||||||
|
// function params initialization.
|
||||||
|
static VarNode* allocParam(S32 lineNumber, StringTableEntry varName, ExprNode* defaultValue);
|
||||||
|
|
||||||
U32 compile(CodeStream& codeStream, U32 ip, TypeReq type) override;
|
U32 compile(CodeStream& codeStream, U32 ip, TypeReq type) override;
|
||||||
TypeReq getPreferredType() override;
|
TypeReq getPreferredType() override;
|
||||||
ExprNodeName getExprNodeNameEnum() const override { return NameVarNode; }
|
ExprNodeName getExprNodeNameEnum() const override { return NameVarNode; }
|
||||||
|
|
|
||||||
|
|
@ -206,6 +206,19 @@ VarNode* VarNode::alloc(S32 lineNumber, StringTableEntry varName, ExprNode* arra
|
||||||
ret->optimizedNode = NULL;
|
ret->optimizedNode = NULL;
|
||||||
ret->varName = varName;
|
ret->varName = varName;
|
||||||
ret->arrayIndex = arrayIndex;
|
ret->arrayIndex = arrayIndex;
|
||||||
|
ret->defaultValue = NULL;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
VarNode* VarNode::allocParam(S32 lineNumber, StringTableEntry varName, ExprNode* defaultValue)
|
||||||
|
{
|
||||||
|
VarNode* ret = (VarNode*)consoleAlloc(sizeof(VarNode));
|
||||||
|
constructInPlace(ret);
|
||||||
|
ret->dbgLineNumber = lineNumber;
|
||||||
|
ret->optimizedNode = NULL;
|
||||||
|
ret->varName = varName;
|
||||||
|
ret->arrayIndex = NULL;
|
||||||
|
ret->defaultValue = defaultValue;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1529,6 +1529,19 @@ U32 FunctionDeclStmtNode::compileStmt(CodeStream& codeStream, U32 ip)
|
||||||
|
|
||||||
CodeBlock::smInFunction = false;
|
CodeBlock::smInFunction = false;
|
||||||
|
|
||||||
|
// check for argument setup
|
||||||
|
for (VarNode* walk = args; walk; walk = (VarNode*)((StmtNode*)walk)->getNext())
|
||||||
|
{
|
||||||
|
if (walk->defaultValue)
|
||||||
|
{
|
||||||
|
TypeReq walkType = walk->defaultValue->getPreferredType();
|
||||||
|
if (walkType == TypeReqNone)
|
||||||
|
walkType = TypeReqString;
|
||||||
|
|
||||||
|
ip = walk->defaultValue->compile(codeStream, ip, walkType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
codeStream.emit(OP_FUNC_DECL);
|
codeStream.emit(OP_FUNC_DECL);
|
||||||
codeStream.emitSTE(fnName);
|
codeStream.emitSTE(fnName);
|
||||||
codeStream.emitSTE(nameSpace);
|
codeStream.emitSTE(nameSpace);
|
||||||
|
|
@ -1538,11 +1551,22 @@ U32 FunctionDeclStmtNode::compileStmt(CodeStream& codeStream, U32 ip)
|
||||||
const U32 endIp = codeStream.emit(0);
|
const U32 endIp = codeStream.emit(0);
|
||||||
codeStream.emit(argc);
|
codeStream.emit(argc);
|
||||||
const U32 localNumVarsIP = codeStream.emit(0);
|
const U32 localNumVarsIP = codeStream.emit(0);
|
||||||
|
|
||||||
for (VarNode* walk = args; walk; walk = (VarNode*)((StmtNode*)walk)->getNext())
|
for (VarNode* walk = args; walk; walk = (VarNode*)((StmtNode*)walk)->getNext())
|
||||||
{
|
{
|
||||||
StringTableEntry name = walk->varName;
|
StringTableEntry name = walk->varName;
|
||||||
codeStream.emit(getFuncVars(dbgLineNumber)->lookup(name, dbgLineNumber));
|
codeStream.emit(getFuncVars(dbgLineNumber)->lookup(name, dbgLineNumber));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check for argument setup
|
||||||
|
for (VarNode* walk = args; walk; walk = (VarNode*)((StmtNode*)walk)->getNext())
|
||||||
|
{
|
||||||
|
U32 flags = 0;
|
||||||
|
if (walk->defaultValue) flags |= 0x1;
|
||||||
|
|
||||||
|
codeStream.emit(flags);
|
||||||
|
}
|
||||||
|
|
||||||
CodeBlock::smInFunction = true;
|
CodeBlock::smInFunction = true;
|
||||||
ip = compileBlock(stmts, codeStream, ip);
|
ip = compileBlock(stmts, codeStream, ip);
|
||||||
|
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -614,7 +614,22 @@ Con::EvalResult CodeBlock::exec(U32 ip, const char* functionName, Namespace* thi
|
||||||
ConsoleValue& value = argv[i + 1];
|
ConsoleValue& value = argv[i + 1];
|
||||||
Script::gEvalState.moveConsoleValue(reg, (value));
|
Script::gEvalState.moveConsoleValue(reg, (value));
|
||||||
}
|
}
|
||||||
ip = ip + fnArgc + (2 + 6 + 1 + 1);
|
|
||||||
|
if (wantedArgc < fnArgc)
|
||||||
|
{
|
||||||
|
Namespace::Entry* temp = thisNamespace->lookup(thisFunctionName);
|
||||||
|
for (; i < fnArgc; i++)
|
||||||
|
{
|
||||||
|
S32 reg = code[ip + (2 + 6 + 1 + 1) + i];
|
||||||
|
if (temp->mArgFlags[i] & 0x1)
|
||||||
|
{
|
||||||
|
ConsoleValue& value = temp->mDefaultValues[i];
|
||||||
|
Script::gEvalState.moveConsoleValue(reg, (value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ip = ip + fnArgc + (2 + 6 + 1 + 1) + fnArgc;
|
||||||
curFloatTable = functionFloats;
|
curFloatTable = functionFloats;
|
||||||
curStringTable = functionStrings;
|
curStringTable = functionStrings;
|
||||||
curStringTableLen = functionStringsMaxLen;
|
curStringTableLen = functionStringsMaxLen;
|
||||||
|
|
@ -736,8 +751,39 @@ Con::EvalResult CodeBlock::exec(U32 ip, const char* functionName, Namespace* thi
|
||||||
curNSDocBlock = NULL;
|
curNSDocBlock = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Namespace::relinkPackages();
|
|
||||||
|
|
||||||
|
U32 fnArgc = code[ip + 2 + 6];
|
||||||
|
|
||||||
|
// Compute pointer to the register mapping like exec() does.
|
||||||
|
U32 readPtr = ip + 2 + 6 + 1; // points to the slot after argc (localNumVarsIP)
|
||||||
|
readPtr += 1; // skip localNumVarsIP
|
||||||
|
readPtr += fnArgc; // skip register mapping
|
||||||
|
|
||||||
|
Namespace::Entry* temp = ns->lookup(fnName);
|
||||||
|
|
||||||
|
temp->mArgFlags.setSize(fnArgc);
|
||||||
|
temp->mDefaultValues.setSize(fnArgc);
|
||||||
|
|
||||||
|
// Read flags sequentially
|
||||||
|
for (U32 fa = 0; fa < fnArgc; ++fa)
|
||||||
|
{
|
||||||
|
temp->mArgFlags[fa] = code[readPtr++];
|
||||||
|
}
|
||||||
|
|
||||||
|
// this might seem weird but because of the order
|
||||||
|
// the stack accumulates consoleValues we cant be sure
|
||||||
|
// all args have a console value, and we need to pop
|
||||||
|
// the stack, do this in reverse order.
|
||||||
|
for (S32 fa = S32(fnArgc - 1); fa >= 0; fa--)
|
||||||
|
{
|
||||||
|
if (temp->mArgFlags[fa] & 0x1)
|
||||||
|
{
|
||||||
|
temp->mDefaultValues[fa] = stack[_STK--];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Namespace::relinkPackages();
|
||||||
// If we had a docblock, it's definitely not valid anymore, so clear it out.
|
// If we had a docblock, it's definitely not valid anymore, so clear it out.
|
||||||
curFNDocBlock = NULL;
|
curFNDocBlock = NULL;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue