mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2025-01-18 06:31:45 +00:00
- added automatic type deduction capabilities for local variables. If you type 'let variable = value;' the type of 'variable' will be deduced from the given value. This is mostly of interest for type casting pointers, because 'let p = Classtype(objectvar);' does not require writing the class type name twice.
This commit is contained in:
parent
67bdac5227
commit
f722967abe
10 changed files with 42 additions and 3 deletions
|
@ -74,6 +74,7 @@ TArray<PClass *> PClass::AllClasses;
|
||||||
bool PClass::bShutdown;
|
bool PClass::bShutdown;
|
||||||
|
|
||||||
PErrorType *TypeError;
|
PErrorType *TypeError;
|
||||||
|
PErrorType *TypeAuto;
|
||||||
PVoidType *TypeVoid;
|
PVoidType *TypeVoid;
|
||||||
PInt *TypeSInt8, *TypeUInt8;
|
PInt *TypeSInt8, *TypeUInt8;
|
||||||
PInt *TypeSInt16, *TypeUInt16;
|
PInt *TypeSInt16, *TypeUInt16;
|
||||||
|
@ -570,6 +571,7 @@ void PType::StaticInit()
|
||||||
|
|
||||||
// Create types and add them type the type table.
|
// Create types and add them type the type table.
|
||||||
TypeTable.AddType(TypeError = new PErrorType);
|
TypeTable.AddType(TypeError = new PErrorType);
|
||||||
|
TypeTable.AddType(TypeAuto = new PErrorType(2));
|
||||||
TypeTable.AddType(TypeVoid = new PVoidType);
|
TypeTable.AddType(TypeVoid = new PVoidType);
|
||||||
TypeTable.AddType(TypeSInt8 = new PInt(1, false));
|
TypeTable.AddType(TypeSInt8 = new PInt(1, false));
|
||||||
TypeTable.AddType(TypeUInt8 = new PInt(1, true));
|
TypeTable.AddType(TypeUInt8 = new PInt(1, true));
|
||||||
|
|
|
@ -370,7 +370,7 @@ class PErrorType : public PType
|
||||||
{
|
{
|
||||||
DECLARE_CLASS(PErrorType, PType);
|
DECLARE_CLASS(PErrorType, PType);
|
||||||
public:
|
public:
|
||||||
PErrorType() : PType(0, 1) {}
|
PErrorType(int which = 1) : PType(0, which) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class PVoidType : public PType
|
class PVoidType : public PType
|
||||||
|
@ -930,6 +930,7 @@ PPrototype *NewPrototype(const TArray<PType *> &rettypes, const TArray<PType *>
|
||||||
// Built-in types -----------------------------------------------------------
|
// Built-in types -----------------------------------------------------------
|
||||||
|
|
||||||
extern PErrorType *TypeError;
|
extern PErrorType *TypeError;
|
||||||
|
extern PErrorType *TypeAuto;
|
||||||
extern PVoidType *TypeVoid;
|
extern PVoidType *TypeVoid;
|
||||||
extern PInt *TypeSInt8, *TypeUInt8;
|
extern PInt *TypeSInt8, *TypeUInt8;
|
||||||
extern PInt *TypeSInt16, *TypeUInt16;
|
extern PInt *TypeSInt16, *TypeUInt16;
|
||||||
|
|
|
@ -721,6 +721,7 @@ xx(State)
|
||||||
xx(Fixed)
|
xx(Fixed)
|
||||||
xx(Vector2)
|
xx(Vector2)
|
||||||
xx(Vector3)
|
xx(Vector3)
|
||||||
|
xx(let)
|
||||||
|
|
||||||
xx(Min)
|
xx(Min)
|
||||||
xx(Max)
|
xx(Max)
|
||||||
|
|
|
@ -183,6 +183,7 @@ std2:
|
||||||
'deprecated' { RET(TK_Deprecated); }
|
'deprecated' { RET(TK_Deprecated); }
|
||||||
'action' { RET(TK_Action); }
|
'action' { RET(TK_Action); }
|
||||||
'readonly' { RET(TK_ReadOnly); }
|
'readonly' { RET(TK_ReadOnly); }
|
||||||
|
'let' { RET(TK_Let); }
|
||||||
|
|
||||||
/* Actor state options */
|
/* Actor state options */
|
||||||
'bright' { RET(StateOptions ? TK_Bright : TK_Identifier); }
|
'bright' { RET(StateOptions ? TK_Bright : TK_Identifier); }
|
||||||
|
|
|
@ -142,4 +142,5 @@ xx(TK_NoDelay, "'nodelay'")
|
||||||
xx(TK_Offset, "'offset'")
|
xx(TK_Offset, "'offset'")
|
||||||
xx(TK_Slow, "'slow'")
|
xx(TK_Slow, "'slow'")
|
||||||
xx(TK_Bright, "'bright'")
|
xx(TK_Bright, "'bright'")
|
||||||
|
xx(TK_Let, "'let'")
|
||||||
#undef xx
|
#undef xx
|
||||||
|
|
|
@ -9964,17 +9964,43 @@ FxExpression *FxLocalVariableDeclaration::Resolve(FCompileContext &ctx)
|
||||||
delete this;
|
delete this;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
if (ValueType->RegType == REGT_NIL)
|
if (ValueType->RegType == REGT_NIL && ValueType != TypeAuto)
|
||||||
{
|
{
|
||||||
auto sfunc = static_cast<VMScriptFunction *>(ctx.Function->Variants[0].Implementation);
|
auto sfunc = static_cast<VMScriptFunction *>(ctx.Function->Variants[0].Implementation);
|
||||||
StackOffset = sfunc->AllocExtraStack(ValueType);
|
StackOffset = sfunc->AllocExtraStack(ValueType);
|
||||||
// Todo: Process the compound initializer once implemented.
|
// Todo: Process the compound initializer once implemented.
|
||||||
|
if (Init != nullptr)
|
||||||
|
{
|
||||||
|
ScriptPosition.Message(MSG_ERROR, "Cannot initialize non-scalar variable %s here", Name.GetChars());
|
||||||
|
delete this;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else if (ValueType !=TypeAuto)
|
||||||
{
|
{
|
||||||
if (Init) Init = new FxTypeCast(Init, ValueType, false);
|
if (Init) Init = new FxTypeCast(Init, ValueType, false);
|
||||||
SAFE_RESOLVE_OPT(Init, ctx);
|
SAFE_RESOLVE_OPT(Init, ctx);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (Init == nullptr)
|
||||||
|
{
|
||||||
|
ScriptPosition.Message(MSG_ERROR, "Automatic type deduction requires an initializer for variable %s", Name.GetChars());
|
||||||
|
delete this;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
SAFE_RESOLVE_OPT(Init, ctx);
|
||||||
|
if (Init->ValueType->RegType == REGT_NIL)
|
||||||
|
{
|
||||||
|
ScriptPosition.Message(MSG_ERROR, "Cannot initialize non-scalar variable %s here", Name.GetChars());
|
||||||
|
delete this;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
ValueType = Init->ValueType;
|
||||||
|
// check for undersized ints and floats. These are not allowed as local variables.
|
||||||
|
if (IsInteger() && ValueType->Align < sizeof(int)) ValueType = TypeSInt32;
|
||||||
|
else if (IsFloat() && ValueType->Align < sizeof(double)) ValueType = TypeFloat64;
|
||||||
|
}
|
||||||
if (Name != NAME_None)
|
if (Name != NAME_None)
|
||||||
{
|
{
|
||||||
for (auto l : ctx.Block->LocalVars)
|
for (auto l : ctx.Block->LocalVars)
|
||||||
|
|
|
@ -704,6 +704,7 @@ type_name1(X) ::= NAME(T). { X.Int = ZCC_Name; X.SourceLoc = T.SourceLoc; }
|
||||||
type_name1(X) ::= SOUND(T). { X.Int = ZCC_Sound; X.SourceLoc = T.SourceLoc; }
|
type_name1(X) ::= SOUND(T). { X.Int = ZCC_Sound; X.SourceLoc = T.SourceLoc; }
|
||||||
type_name1(X) ::= STATE(T). { X.Int = ZCC_State; X.SourceLoc = T.SourceLoc; }
|
type_name1(X) ::= STATE(T). { X.Int = ZCC_State; X.SourceLoc = T.SourceLoc; }
|
||||||
type_name1(X) ::= COLOR(T). { X.Int = ZCC_Color; X.SourceLoc = T.SourceLoc; }
|
type_name1(X) ::= COLOR(T). { X.Int = ZCC_Color; X.SourceLoc = T.SourceLoc; }
|
||||||
|
type_name1(X) ::= LET(T). { X.Int = ZCC_Let; X.SourceLoc = T.SourceLoc; }
|
||||||
|
|
||||||
type_name(X) ::= type_name1(A).
|
type_name(X) ::= type_name1(A).
|
||||||
{
|
{
|
||||||
|
|
|
@ -1449,6 +1449,10 @@ PType *ZCCCompiler::DetermineType(PType *outertype, ZCC_TreeNode *field, FName n
|
||||||
retval = TypeSound;
|
retval = TypeSound;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ZCC_Let:
|
||||||
|
retval = TypeAuto;
|
||||||
|
break;
|
||||||
|
|
||||||
case ZCC_UserType:
|
case ZCC_UserType:
|
||||||
// statelabel et.al. are not tokens - there really is no need to, it works just as well as an identifier. Maybe the same should be done for some other types, too?
|
// statelabel et.al. are not tokens - there really is no need to, it works just as well as an identifier. Maybe the same should be done for some other types, too?
|
||||||
switch (btype->UserType->Id)
|
switch (btype->UserType->Id)
|
||||||
|
|
|
@ -201,6 +201,7 @@ static void InitTokenMap()
|
||||||
TOKENDEF2(TK_State, ZCC_STATE, NAME_State);
|
TOKENDEF2(TK_State, ZCC_STATE, NAME_State);
|
||||||
TOKENDEF2(TK_Color, ZCC_COLOR, NAME_Color);
|
TOKENDEF2(TK_Color, ZCC_COLOR, NAME_Color);
|
||||||
TOKENDEF2(TK_Sound, ZCC_SOUND, NAME_Sound);
|
TOKENDEF2(TK_Sound, ZCC_SOUND, NAME_Sound);
|
||||||
|
TOKENDEF2(TK_Let, ZCC_LET, NAME_let);
|
||||||
|
|
||||||
TOKENDEF (TK_Identifier, ZCC_IDENTIFIER);
|
TOKENDEF (TK_Identifier, ZCC_IDENTIFIER);
|
||||||
TOKENDEF (TK_StringConst, ZCC_STRCONST);
|
TOKENDEF (TK_StringConst, ZCC_STRCONST);
|
||||||
|
|
|
@ -131,6 +131,7 @@ enum EZCCBuiltinType
|
||||||
ZCC_Sound,
|
ZCC_Sound,
|
||||||
|
|
||||||
ZCC_UserType,
|
ZCC_UserType,
|
||||||
|
ZCC_Let,
|
||||||
|
|
||||||
ZCC_NUM_BUILT_IN_TYPES
|
ZCC_NUM_BUILT_IN_TYPES
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue