Map<K,V> and MapIterator<K,V> for ZScript
This commit is contained in:
parent
1e5e65546d
commit
8b6a714d41
23 changed files with 2354 additions and 28 deletions
|
|
@ -502,6 +502,16 @@ static void PrintMapType(FLispString &out, const ZCC_TreeNode *node)
|
|||
out.Close();
|
||||
}
|
||||
|
||||
static void PrintMapIteratorType(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
ZCC_MapIteratorType *tnode = (ZCC_MapIteratorType *)node;
|
||||
out.Open("map-iterator-type");
|
||||
PrintNodes(out, tnode->ArraySize);
|
||||
PrintNodes(out, tnode->KeyType);
|
||||
PrintNodes(out, tnode->ValueType);
|
||||
out.Close();
|
||||
}
|
||||
|
||||
static void PrintDynArrayType(FLispString &out, const ZCC_TreeNode *node)
|
||||
{
|
||||
ZCC_DynArrayType *tnode = (ZCC_DynArrayType *)node;
|
||||
|
|
@ -955,6 +965,7 @@ static const NodePrinterFunc TreeNodePrinter[] =
|
|||
PrintType,
|
||||
PrintBasicType,
|
||||
PrintMapType,
|
||||
PrintMapIteratorType,
|
||||
PrintDynArrayType,
|
||||
PrintClassType,
|
||||
PrintExpression,
|
||||
|
|
|
|||
|
|
@ -932,7 +932,7 @@ type_name(X) ::= DOT dottable_id(A).
|
|||
/* Type names can also be used as identifiers in contexts where type names
|
||||
* are not normally allowed. */
|
||||
%fallback IDENTIFIER
|
||||
SBYTE BYTE SHORT USHORT INT UINT BOOL FLOAT DOUBLE STRING VECTOR2 VECTOR3 VECTOR4 NAME MAP ARRAY VOID STATE COLOR SOUND UINT8 INT8 UINT16 INT16 PROPERTY.
|
||||
SBYTE BYTE SHORT USHORT INT UINT BOOL FLOAT DOUBLE STRING VECTOR2 VECTOR3 VECTOR4 NAME MAP MAPITERATOR ARRAY VOID STATE COLOR SOUND UINT8 INT8 UINT16 INT16 PROPERTY.
|
||||
|
||||
/* Aggregate types */
|
||||
%type aggregate_type {ZCC_Type *}
|
||||
|
|
@ -944,7 +944,7 @@ type_name(X) ::= DOT dottable_id(A).
|
|||
%type array_size{ZCC_Expression *}
|
||||
%type array_size_expr{ZCC_Expression *}
|
||||
|
||||
aggregate_type(X) ::= MAP(T) LT type_or_array(A) COMMA type_or_array(B) GT. /* Hash table */
|
||||
aggregate_type(X) ::= MAP(T) LT type_or_array(A) COMMA type_or_array(B) GT. /* ZSMap<K, V> */
|
||||
{
|
||||
NEW_AST_NODE(MapType,map,T);
|
||||
map->KeyType = A;
|
||||
|
|
@ -952,6 +952,14 @@ aggregate_type(X) ::= MAP(T) LT type_or_array(A) COMMA type_or_array(B) GT. /* H
|
|||
X = map;
|
||||
}
|
||||
|
||||
aggregate_type(X) ::= MAPITERATOR(T) LT type_or_array(A) COMMA type_or_array(B) GT. /* ZSMapIterator<K, V> */
|
||||
{
|
||||
NEW_AST_NODE(MapIteratorType,map_it,T);
|
||||
map_it->KeyType = A;
|
||||
map_it->ValueType = B;
|
||||
X = map_it;
|
||||
}
|
||||
|
||||
aggregate_type(X) ::= ARRAY(T) LT type_or_array(A) GT. /* TArray<type> */
|
||||
{
|
||||
NEW_AST_NODE(DynArrayType,arr,T);
|
||||
|
|
|
|||
|
|
@ -1853,16 +1853,96 @@ PType *ZCCCompiler::DetermineType(PType *outertype, ZCC_TreeNode *field, FName n
|
|||
}
|
||||
|
||||
case AST_MapType:
|
||||
if (allowarraytypes)
|
||||
{
|
||||
if(AST.ParseVersion < MakeVersion(4, 10, 0))
|
||||
{
|
||||
Error(field, "%s: Map types not implemented yet", name.GetChars());
|
||||
// Todo: Decide what we allow here and if it makes sense to allow more complex constructs.
|
||||
auto mtype = static_cast<ZCC_MapType *>(ztype);
|
||||
retval = NewMap(DetermineType(outertype, field, name, mtype->KeyType, false, false), DetermineType(outertype, field, name, mtype->ValueType, false, false));
|
||||
Error(field, "Map not accessible to ZScript version %d.%d.%d", AST.ParseVersion.major, AST.ParseVersion.minor, AST.ParseVersion.revision);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
// Todo: Decide what we allow here and if it makes sense to allow more complex constructs.
|
||||
auto mtype = static_cast<ZCC_MapType *>(ztype);
|
||||
|
||||
auto keytype = DetermineType(outertype, field, name, mtype->KeyType, false, false);
|
||||
auto valuetype = DetermineType(outertype, field, name, mtype->ValueType, false, false);
|
||||
|
||||
if (keytype->GetRegType() == REGT_INT)
|
||||
{
|
||||
if (keytype->Size != 4)
|
||||
{
|
||||
Error(field, "Map<%s , ...> not implemented yet", keytype->DescriptiveName());
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (keytype->GetRegType() != REGT_STRING)
|
||||
{
|
||||
Error(field, "Map<%s , ...> not implemented yet", keytype->DescriptiveName());
|
||||
break;
|
||||
}
|
||||
|
||||
switch(valuetype->GetRegType())
|
||||
{
|
||||
case REGT_FLOAT:
|
||||
case REGT_INT:
|
||||
case REGT_STRING:
|
||||
case REGT_POINTER:
|
||||
if (valuetype->GetRegCount() > 1)
|
||||
{
|
||||
Error(field, "%s : Base type for map value types must be integral, but got %s", name.GetChars(), valuetype->DescriptiveName());
|
||||
break;
|
||||
}
|
||||
|
||||
retval = NewMap(keytype, valuetype);
|
||||
break;
|
||||
default:
|
||||
Error(field, "%s: Base type for map value types must be integral, but got %s", name.GetChars(), valuetype->DescriptiveName());
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case AST_MapIteratorType:
|
||||
{
|
||||
if(AST.ParseVersion < MakeVersion(4, 10, 0))
|
||||
{
|
||||
Error(field, "MapIterator not accessible to ZScript version %d.%d.%d", AST.ParseVersion.major, AST.ParseVersion.minor, AST.ParseVersion.revision);
|
||||
break;
|
||||
}
|
||||
// Todo: Decide what we allow here and if it makes sense to allow more complex constructs.
|
||||
auto mtype = static_cast<ZCC_MapIteratorType *>(ztype);
|
||||
|
||||
auto keytype = DetermineType(outertype, field, name, mtype->KeyType, false, false);
|
||||
auto valuetype = DetermineType(outertype, field, name, mtype->ValueType, false, false);
|
||||
|
||||
if (keytype->GetRegType() == REGT_INT)
|
||||
{
|
||||
if (keytype->Size != 4)
|
||||
{
|
||||
Error(field, "MapIterator<%s , ...> not implemented yet", keytype->DescriptiveName());
|
||||
}
|
||||
}
|
||||
else if (keytype->GetRegType() != REGT_STRING)
|
||||
{
|
||||
Error(field, "MapIterator<%s , ...> not implemented yet", keytype->DescriptiveName());
|
||||
}
|
||||
|
||||
switch(valuetype->GetRegType())
|
||||
{
|
||||
case REGT_FLOAT:
|
||||
case REGT_INT:
|
||||
case REGT_STRING:
|
||||
case REGT_POINTER:
|
||||
if (valuetype->GetRegCount() > 1)
|
||||
{
|
||||
Error(field, "%s : Base type for map value types must be integral, but got %s", name.GetChars(), valuetype->DescriptiveName());
|
||||
break;
|
||||
}
|
||||
retval = NewMapIterator(keytype, valuetype);
|
||||
break;
|
||||
default:
|
||||
Error(field, "%s: Base type for map value types must be integral, but got %s", name.GetChars(), valuetype->DescriptiveName());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case AST_DynArrayType:
|
||||
{
|
||||
auto atype = static_cast<ZCC_DynArrayType *>(ztype);
|
||||
|
|
@ -2357,7 +2437,7 @@ void ZCCCompiler::CompileFunction(ZCC_StructWork *c, ZCC_FuncDeclarator *f, bool
|
|||
{
|
||||
auto type = DetermineType(c->Type(), p, f->Name, p->Type, false, false);
|
||||
int flags = 0;
|
||||
if ((type->isStruct() && type != TypeVector2 && type != TypeVector3 && type != TypeVector4 && type != TypeQuaternion && type != TypeFVector2 && type != TypeFVector3 && type != TypeFVector4 && type != TypeFQuaternion) || type->isDynArray())
|
||||
if ((type->isStruct() && type != TypeVector2 && type != TypeVector3 && type != TypeVector4 && type != TypeQuaternion && type != TypeFVector2 && type != TypeFVector3 && type != TypeFVector4 && type != TypeFQuaternion) || type->isDynArray() || type->isMap() || type->isMapIterator())
|
||||
{
|
||||
// Structs are being passed by pointer, but unless marked 'out' that pointer must be readonly.
|
||||
type = NewPointer(type /*, !(p->Flags & ZCC_Out)*/);
|
||||
|
|
|
|||
|
|
@ -220,6 +220,7 @@ static void InitTokenMap()
|
|||
TOKENDEF2(TK_Vector3, ZCC_VECTOR3, NAME_Vector3);
|
||||
TOKENDEF2(TK_Name, ZCC_NAME, NAME_Name);
|
||||
TOKENDEF2(TK_Map, ZCC_MAP, NAME_Map);
|
||||
TOKENDEF2(TK_MapIterator, ZCC_MAPITERATOR,NAME_MapIterator);
|
||||
TOKENDEF2(TK_Array, ZCC_ARRAY, NAME_Array);
|
||||
TOKENDEF2(TK_Include, ZCC_INCLUDE, NAME_Include);
|
||||
TOKENDEF (TK_Void, ZCC_VOID);
|
||||
|
|
@ -896,6 +897,19 @@ ZCC_TreeNode *TreeNodeDeepCopy_Internal(ZCC_AST *ast, ZCC_TreeNode *orig, bool c
|
|||
break;
|
||||
}
|
||||
|
||||
case AST_MapIteratorType:
|
||||
{
|
||||
TreeNodeDeepCopy_Start(MapIteratorType);
|
||||
|
||||
// ZCC_Type
|
||||
copy->ArraySize = static_cast<ZCC_Expression *>(TreeNodeDeepCopy_Internal(ast, origCasted->ArraySize, true, copiedNodesList));
|
||||
// AST_MapIteratorType
|
||||
copy->KeyType = static_cast<ZCC_Type *>(TreeNodeDeepCopy_Internal(ast, origCasted->KeyType, true, copiedNodesList));
|
||||
copy->ValueType = static_cast<ZCC_Type *>(TreeNodeDeepCopy_Internal(ast, origCasted->ValueType, true, copiedNodesList));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case AST_DynArrayType:
|
||||
{
|
||||
TreeNodeDeepCopy_Start(DynArrayType);
|
||||
|
|
|
|||
|
|
@ -98,6 +98,7 @@ enum EZCCTreeNodeType
|
|||
AST_Type,
|
||||
AST_BasicType,
|
||||
AST_MapType,
|
||||
AST_MapIteratorType,
|
||||
AST_DynArrayType,
|
||||
AST_ClassType,
|
||||
AST_Expression,
|
||||
|
|
@ -367,6 +368,12 @@ struct ZCC_MapType : ZCC_Type
|
|||
ZCC_Type *ValueType;
|
||||
};
|
||||
|
||||
struct ZCC_MapIteratorType : ZCC_Type
|
||||
{
|
||||
ZCC_Type *KeyType;
|
||||
ZCC_Type *ValueType;
|
||||
};
|
||||
|
||||
struct ZCC_DynArrayType : ZCC_Type
|
||||
{
|
||||
ZCC_Type *ElementType;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue