diff --git a/src/common/engine/sc_man.h b/src/common/engine/sc_man.h index 5873523a12..d90da64746 100644 --- a/src/common/engine/sc_man.h +++ b/src/common/engine/sc_man.h @@ -85,6 +85,11 @@ public: ParseVersion = ver; } + bool CheckParseVersion(VersionInfo ver) + { + return ParseVersion >= ver; + } + void SetCMode(bool cmode); void SetNoOctals(bool cmode) { NoOctals = cmode; } void SetNoFatalErrors(bool cmode) { NoFatalErrors = cmode; } diff --git a/src/common/scripting/frontend/zcc-parse.lemon b/src/common/scripting/frontend/zcc-parse.lemon index eed7553551..85e3a762b4 100644 --- a/src/common/scripting/frontend/zcc-parse.lemon +++ b/src/common/scripting/frontend/zcc-parse.lemon @@ -980,6 +980,7 @@ type_name(X) ::= DOT dottable_id(A). /* Aggregate types */ %type aggregate_type {ZCC_Type *} +%type aggregate_type_pre {ZCC_Type *} %type type {ZCC_Type *} %type type_list {ZCC_Type *} %type type_list_or_void {ZCC_Type *} @@ -988,30 +989,92 @@ 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. /* ZSMap */ +aggregate_type_pre(X) ::= MAP(T) LT type_or_array(A) COMMA type_or_array(B). /* ZSMap */ { NEW_AST_NODE(MapType,map,T); map->KeyType = A; map->ValueType = B; X = map; + X->ArraySize = NULL; } -aggregate_type(X) ::= MAPITERATOR(T) LT type_or_array(A) COMMA type_or_array(B) GT. /* ZSMapIterator */ +aggregate_type_pre(X) ::= MAPITERATOR(T) LT type_or_array(A) COMMA type_or_array(B). /* ZSMapIterator */ { NEW_AST_NODE(MapIteratorType,map_it,T); map_it->KeyType = A; map_it->ValueType = B; X = map_it; + X->ArraySize = NULL; } -aggregate_type(X) ::= ARRAY(T) LT type_or_array(A) GT. /* TArray */ +aggregate_type_pre(X) ::= ARRAY(T) LT type_or_array(A). /* TArray */ { NEW_AST_NODE(DynArrayType,arr,T); arr->ElementType = A; X = arr; + X->ArraySize = NULL; } -aggregate_type(X) ::= func_ptr_type(A). { X = A; /*X-overwrites-A*/ } +aggregate_type_pre(X) ::= func_ptr_type(A). { X = A; /*X-overwrites-A*/ X->ArraySize = NULL; } + +aggregate_type_pre(X) ::= CLASS(T) LT dottable_id(A). /* class */ +{ + NEW_AST_NODE(ClassType,cls,T); + cls->Restriction = A; + X = cls; + X->ArraySize = NULL; +} + +aggregate_type(X) ::= aggregate_type_pre(A) GT. { X = A; X->ArraySize = NULL; } + +aggregate_type(X) ::= MAP(T) LT type_or_array(A) COMMA aggregate_type_pre(B) RSH. /* ZSMap> */ +{ + if(!stat->sc->CheckParseVersion(MakeVersion(4, 15, 1))) + { + stat->sc->ScriptMessage(">> without space in parametrized types only supported for zscript >= 4.15.1"); + FScriptPosition::ErrorCounter++; + } + NEW_AST_NODE(MapType,map,T); + map->KeyType = A; + map->ValueType = B; + X = map; + X->ArraySize = NULL; +} + +aggregate_type(X) ::= MAPITERATOR(T) LT type_or_array(A) COMMA aggregate_type_pre(B) RSH. /* ZSMapIterator> */ +{ + if(!stat->sc->CheckParseVersion(MakeVersion(4, 15, 1))) + { + stat->sc->ScriptMessage(">> without space in parametrized types only supported for zscript >= 4.15.1"); + FScriptPosition::ErrorCounter++; + } + NEW_AST_NODE(MapIteratorType,map_it,T); + map_it->KeyType = A; + map_it->ValueType = B; + X = map_it; + X->ArraySize = NULL; +} + +aggregate_type(X) ::= ARRAY(T) LT aggregate_type_pre(A) RSH. /* TArray> */ +{ + if(!stat->sc->CheckParseVersion(MakeVersion(4, 15, 1))) + { + stat->sc->ScriptMessage(">> without space in parametrized types only supported for zscript >= 4.15.1"); + FScriptPosition::ErrorCounter++; + } + NEW_AST_NODE(DynArrayType,arr,T); + arr->ElementType = A; + X = arr; + X->ArraySize = NULL; +} + +aggregate_type(X) ::= CLASS(T). /* class */ +{ + NEW_AST_NODE(ClassType,cls,T); + cls->Restriction = NULL; + X = cls; + X->ArraySize = NULL; +} %type func_ptr_type {ZCC_FuncPtrType *} %type func_ptr_params {ZCC_FuncPtrParamDecl *} @@ -1025,7 +1088,7 @@ fn_ptr_flag(X) ::= CLEARSCOPE. { X.Int = ZCC_ClearScope; } //fn_ptr_flag(X) ::= VIRTUALSCOPE. { X.Int = ZCC_VirtualScope; } //virtual scope not allowed -func_ptr_type(X) ::= FNTYPE(T) LT fn_ptr_flag(F) type_list_or_void(A) LPAREN func_ptr_params(B) RPAREN GT. /* Function<...(...)> */ +func_ptr_type(X) ::= FNTYPE(T) LT fn_ptr_flag(F) type_list_or_void(A) LPAREN func_ptr_params(B) RPAREN. /* Function<...(...)> */ { NEW_AST_NODE(FuncPtrType,fn_ptr,T); fn_ptr->RetType = A; @@ -1034,7 +1097,7 @@ func_ptr_type(X) ::= FNTYPE(T) LT fn_ptr_flag(F) type_list_or_void(A) LPAREN fun X = fn_ptr; } -func_ptr_type(X) ::= FNTYPE(T) LT VOID GT. /* Function */ +func_ptr_type(X) ::= FNTYPE(T) LT VOID. /* Function */ { NEW_AST_NODE(FuncPtrType,fn_ptr,T); fn_ptr->RetType = nullptr; @@ -1076,15 +1139,6 @@ func_ptr_param(X) ::= func_param_flags(A) type(B) AND. X = parm; } -aggregate_type(X) ::= CLASS(T) class_restrictor(A). /* class */ -{ - NEW_AST_NODE(ClassType,cls,T); - cls->Restriction = A; - X = cls; -} -class_restrictor(X) ::= . { X = NULL; } -class_restrictor(X) ::= LT dottable_id(A) GT. { X = A; /*X-overwrites-A*/ } - type(X) ::= type_name(A). { X = A; /*X-overwrites-A*/ X->ArraySize = NULL; } type(X) ::= aggregate_type(A). { X = A; /*X-overwrites-A*/ X->ArraySize = NULL; }