Skip to content

ZScript improvements 2 #2972

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Mar 5, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions src/common/engine/sc_man.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,11 @@ class FScanner
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; }
Expand Down
2 changes: 1 addition & 1 deletion src/common/scripting/core/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ class PType : public PTypeBase
EScopeFlags ScopeFlags = (EScopeFlags)0;
bool SizeKnown = true;

bool TypeInternal = false;
bool VMInternalStruct = false;
bool TypeDeprecated = false; // mVersion is deprecation version, not minimum version
FString mDeprecationMessage;

Expand Down
96 changes: 75 additions & 21 deletions src/common/scripting/frontend/zcc-parse.lemon
Original file line number Diff line number Diff line change
Expand Up @@ -442,12 +442,12 @@ struct_def(X) ::= EXTEND STRUCT(T) IDENTIFIER(A) LBRACE opt_struct_body(B) RBRAC
}

%type struct_flags{ClassFlagsBlock}
struct_flags(X) ::= . { X.Flags = 0; X.Version = {0, 0}; X.DeprecationMessage = NULL; }
struct_flags(X) ::= struct_flags(A) UI. { X.Flags = A.Flags | ZCC_UIFlag; X.Version = A.Version; X.DeprecationMessage = A.DeprecationMessage; }
struct_flags(X) ::= struct_flags(A) PLAY. { X.Flags = A.Flags | ZCC_Play; X.Version = A.Version; X.DeprecationMessage = A.DeprecationMessage; }
struct_flags(X) ::= struct_flags(A) CLEARSCOPE. { X.Flags = A.Flags | ZCC_ClearScope; X.Version = A.Version; X.DeprecationMessage = A.DeprecationMessage; }
struct_flags(X) ::= struct_flags(A) NATIVE. { X.Flags = A.Flags | ZCC_Native; X.Version = A.Version; X.DeprecationMessage = A.DeprecationMessage; }
struct_flags(X) ::= struct_flags(A) INTERNAL. { X.Flags = A.Flags | ZCC_Internal; X.Version = A.Version; X.DeprecationMessage = A.DeprecationMessage; }
struct_flags(X) ::= . { X.Flags = 0; X.Version = {0, 0}; X.DeprecationMessage = NULL; }
struct_flags(X) ::= struct_flags(A) UI. { X.Flags = A.Flags | ZCC_UIFlag; X.Version = A.Version; X.DeprecationMessage = A.DeprecationMessage; }
struct_flags(X) ::= struct_flags(A) PLAY. { X.Flags = A.Flags | ZCC_Play; X.Version = A.Version; X.DeprecationMessage = A.DeprecationMessage; }
struct_flags(X) ::= struct_flags(A) CLEARSCOPE. { X.Flags = A.Flags | ZCC_ClearScope; X.Version = A.Version; X.DeprecationMessage = A.DeprecationMessage; }
struct_flags(X) ::= struct_flags(A) NATIVE. { X.Flags = A.Flags | ZCC_Native; X.Version = A.Version; X.DeprecationMessage = A.DeprecationMessage; }
struct_flags(X) ::= struct_flags(A) UNSAFE LPAREN INTERNAL RPAREN. { X.Flags = A.Flags | ZCC_VMInternalStruct; X.Version = A.Version; X.DeprecationMessage = A.DeprecationMessage; }
struct_flags(X) ::= struct_flags(A) VERSION LPAREN STRCONST(C) RPAREN. { X.Flags = A.Flags | ZCC_Version; X.Version = C.String->GetChars(); X.DeprecationMessage = A.DeprecationMessage; }

struct_flags(X) ::= struct_flags(A) DEPRECATED LPAREN STRCONST(C) opt_deprecation_message(D) RPAREN.
Expand Down Expand Up @@ -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 *}
Expand All @@ -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<K, V> */
aggregate_type_pre(X) ::= MAP(T) LT type_or_array(A) COMMA type_or_array(B). /* ZSMap<K, V> */
{
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<K, V> */
aggregate_type_pre(X) ::= MAPITERATOR(T) LT type_or_array(A) COMMA type_or_array(B). /* ZSMapIterator<K, V> */
{
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<type> */
aggregate_type_pre(X) ::= ARRAY(T) LT type_or_array(A). /* TArray<type> */
{
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<type> */
{
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<K, V<...>> */
{
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<K, V<...>> */
{
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<T<...>> */
{
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<type> */
{
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 *}
Expand All @@ -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;
Expand All @@ -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<void> */
func_ptr_type(X) ::= FNTYPE(T) LT VOID. /* Function<void> */
{
NEW_AST_NODE(FuncPtrType,fn_ptr,T);
fn_ptr->RetType = nullptr;
Expand Down Expand Up @@ -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<type> */
{
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; }

Expand Down
6 changes: 3 additions & 3 deletions src/common/scripting/frontend/zcc_compile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -758,11 +758,11 @@ void ZCCCompiler::CreateStructTypes()
s->strct->Type->mDeprecationMessage = s->strct->DeprecationMessage ? *s->strct->DeprecationMessage : "";
}

if (s->strct->Flags & ZCC_Internal)
if (s->strct->Flags & ZCC_VMInternalStruct)
{
if(fileSystem.GetFileContainer(Lump) == 0)
{
s->strct->Type->TypeInternal = true;
s->strct->Type->VMInternalStruct = true;
}
else
{
Expand Down Expand Up @@ -2214,7 +2214,7 @@ PType *ZCCCompiler::ResolveUserType(PType *outertype, ZCC_BasicType *type, ZCC_I
}

//only allow references to internal types inside internal types
if (ptype->TypeInternal && !outertype->TypeInternal)
if (ptype->VMInternalStruct && !outertype->VMInternalStruct)
{
Error(type, "Type %s not accessible", FName(type->UserType->Id).GetChars());
return TypeError;
Expand Down
1 change: 1 addition & 0 deletions src/common/scripting/frontend/zcc_parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ enum
ZCC_Sealed = 1 << 23,
ZCC_FuncConstUnsafe = 1 << 24,
ZCC_UnsafeClearScope = 1 << 25,
ZCC_VMInternalStruct = 1 << 26,
};

// Function parameter modifiers
Expand Down
22 changes: 13 additions & 9 deletions src/ct_chat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -251,14 +251,18 @@ void CT_Drawer (void)
{
// [MK] allow the status bar to take over chat prompt drawing
bool skip = false;
IFVIRTUALPTR(StatusBar, DBaseStatusBar, DrawChat)

if(StatusBar)
{
FString txt = ChatQueue;
VMValue params[] = { (DObject*)StatusBar, &txt };
int rv;
VMReturn ret(&rv);
VMCall(func, params, countof(params), &ret, 1);
if (!!rv) return;
IFVIRTUALPTR(StatusBar, DBaseStatusBar, DrawChat)
{
FString txt = ChatQueue;
VMValue params[] = { (DObject*)StatusBar, &txt };
int rv;
VMReturn ret(&rv);
VMCall(func, params, countof(params), &ret, 1);
if (!!rv) return;
}
}

FStringf prompt("%s ", GStrings.GetString("TXT_SAY"));
Expand All @@ -269,8 +273,8 @@ void CT_Drawer (void)
scalex = 1;
int scale = active_con_scale(drawer);
int screen_width = twod->GetWidth() / scale;
int screen_height= twod->GetHeight() / scale;
int st_y = StatusBar->GetTopOfStatusbar() / scale;
int screen_height = twod->GetHeight() / scale;
int st_y = StatusBar ? (StatusBar->GetTopOfStatusbar() / scale) : screen_height;

y += ((twod->GetHeight() == viewheight && viewactive) || gamestate != GS_LEVEL) ? screen_height : st_y;

Expand Down
2 changes: 2 additions & 0 deletions src/g_game.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1000,6 +1000,8 @@ bool G_Responder (event_t *ev)
if (gameaction == ga_nothing &&
(demoplayback || gamestate == GS_DEMOSCREEN || gamestate == GS_TITLELEVEL))
{
if (chatmodeon) chatmodeon = 0;

const char *cmd = Bindings.GetBind (ev->data1);

if (ev->type == EV_KeyDown)
Expand Down
6 changes: 3 additions & 3 deletions wadsrc/static/zscript/engine/base.zs
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ struct Vector3
}
*/

struct _ native internal // These are the global variables, the struct is only here to avoid extending the parser for this.
struct _ native unsafe(internal) // These are the global variables, the struct is only here to avoid extending the parser for this.
{
native readonly Array<class> AllClasses;
native internal readonly Map<Name , Service> AllServices;
Expand Down Expand Up @@ -903,7 +903,7 @@ enum EmptyTokenType

// Although String is a builtin type, this is a convenient way to attach methods to it.
// All of these methods are available on strings
struct StringStruct native internal
struct StringStruct native unsafe(internal)
{
native static vararg String Format(String fmt, ...);
native vararg void AppendFormat(String fmt, ...);
Expand Down Expand Up @@ -952,7 +952,7 @@ struct Translation version("2.4")
}

// Convenient way to attach functions to Quat
struct QuatStruct native internal
struct QuatStruct native unsafe(internal)
{
native static Quat SLerp(Quat from, Quat to, double t);
native static Quat NLerp(Quat from, Quat to, double t);
Expand Down
16 changes: 8 additions & 8 deletions wadsrc/static/zscript/engine/dynarrays.zs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// The VM uses 7 integral data types, so for dynamic array support we need one specific set of functions for each of these types.
// Do not use these structs directly, they are incomplete and only needed to create prototypes for the needed functions.

struct DynArray_I8 native internal
struct DynArray_I8 native unsafe(internal)
{
native readonly int Size;

Expand All @@ -21,7 +21,7 @@ struct DynArray_I8 native internal
native void Clear ();
}

struct DynArray_I16 native internal
struct DynArray_I16 native unsafe(internal)
{
native readonly int Size;

Expand All @@ -41,7 +41,7 @@ struct DynArray_I16 native internal
native void Clear ();
}

struct DynArray_I32 native internal
struct DynArray_I32 native unsafe(internal)
{
native readonly int Size;

Expand All @@ -62,7 +62,7 @@ struct DynArray_I32 native internal
native void Clear ();
}

struct DynArray_F32 native internal
struct DynArray_F32 native unsafe(internal)
{
native readonly int Size;

Expand All @@ -82,7 +82,7 @@ struct DynArray_F32 native internal
native void Clear ();
}

struct DynArray_F64 native internal
struct DynArray_F64 native unsafe(internal)
{
native readonly int Size;

Expand All @@ -102,7 +102,7 @@ struct DynArray_F64 native internal
native void Clear ();
}

struct DynArray_Ptr native internal
struct DynArray_Ptr native unsafe(internal)
{
native readonly int Size;

Expand All @@ -122,7 +122,7 @@ struct DynArray_Ptr native internal
native void Clear ();
}

struct DynArray_Obj native internal
struct DynArray_Obj native unsafe(internal)
{
native readonly int Size;

Expand All @@ -142,7 +142,7 @@ struct DynArray_Obj native internal
native void Clear ();
}

struct DynArray_String native internal
struct DynArray_String native unsafe(internal)
{
native readonly int Size;

Expand Down
Loading