diff --git a/src/sc_man_scanner.re b/src/sc_man_scanner.re index d8070b53a..437887d87 100644 --- a/src/sc_man_scanner.re +++ b/src/sc_man_scanner.re @@ -175,6 +175,7 @@ std2: 'meta' { RET(TK_Meta); } 'deprecated' { RET(TK_Deprecated); } 'action' { RET(TK_Action); } + 'readonly' { RET(TK_ReadOnly); } /* other DECORATE top level keywords */ '#include' { RET(TK_Include); } diff --git a/src/sc_man_tokens.h b/src/sc_man_tokens.h index de0815447..e98c457b5 100644 --- a/src/sc_man_tokens.h +++ b/src/sc_man_tokens.h @@ -130,4 +130,5 @@ xx(TK_Fail, "'fail'") xx(TK_Wait, "'wait'") xx(TK_Meta, "'meta'") xx(TK_Deprecated, "'deprecated'") +xx(TK_ReadOnly, "'readonly'") #undef xx diff --git a/src/zscript/zcc-parse.lemon b/src/zscript/zcc-parse.lemon index 63b6a4b91..459432dd1 100644 --- a/src/zscript/zcc-parse.lemon +++ b/src/zscript/zcc-parse.lemon @@ -170,6 +170,7 @@ class_innards ::= class_innards class_member. %type struct_def{ZCC_Struct *} %type enum_def {ZCC_Enum *} %type states_def {ZCC_States *} +%type const_def {ZCC_ConstantDef *} class_member ::= declarator. class_member ::= enum_def. @@ -183,6 +184,7 @@ class_member ::= const_def. %type struct_body{ZCC_TreeNode *} %type struct_member{ZCC_TreeNode *} +%type declarator_no_fun {ZCC_TreeNode *} struct_def(X) ::= STRUCT IDENTIFIER(A) LBRACE struct_body(B) RBRACE opt_semicolon. { @@ -343,7 +345,7 @@ state_action(X) ::= LBRACE error scanner_mode RBRACE. { X = NULL; } state_action(X) ::= state_call(A) scanner_mode SEMICOLON. { X = A; } state_call(X) ::= . { X = NULL; } -state_call(X) ::= IDENTIFIER(A) func_params(B). +state_call(X) ::= IDENTIFIER(A) func_expr_list(B). { NEW_AST_NODE(ExprFuncCall, expr); NEW_AST_NODE(ExprID, func); @@ -394,10 +396,13 @@ vector_size(X) ::= LT INTCONST(A) GT. { X = A.Int; } SBYTE BYTE SHORT USHORT INT UINT BOOL FLOAT DOUBLE STRING VECTOR NAME. /* Aggregate types */ -%type aggregate_type {PType *} -%type type {PType *} -%type type_or_array {PType *} +%type aggregate_type {ZCC_Type *} +%type type {ZCC_Type *} +%type type_list {ZCC_Type *} +%type type_list_or_void {ZCC_Type *} +%type type_or_array {ZCC_Type *} %type class_restrictor {PClass *} +%type array_size{ZCC_Expression *} aggregate_type ::= MAP LT type_or_array COMMA type_or_array GT. /* Hash table */ aggregate_type ::= ARRAY LT type_or_array GT. /* TArray */ @@ -406,24 +411,24 @@ aggregate_type ::= CLASS class_restrictor. /* class */ class_restrictor ::= . class_restrictor ::= LT IDENTIFIER GT. -type(X) ::= type_name(A). { X = A; } -type(X) ::= aggregate_type(A). { X = A; } +type(X) ::= type_name(A). { X = A; A->ArraySize = NULL; } +type(X) ::= aggregate_type(A). { X = A; A->ArraySize = NULL; } -type_or_array ::= type. -type_or_array ::= type array_size. +type_or_array(X) ::= type(A). { X = A; } +type_or_array(X) ::= type(A) array_size(B). { X = A; A->ArraySize = B; } -type_list ::= type_or_array. /* A comma-separated list of types */ -type_list ::= type_list COMMA type_or_array. +type_list(X) ::= type_or_array(A). { X = A; }/* A comma-separated list of types */ +type_list(X) ::= type_list(A) COMMA type_or_array(B). { X = A; A->AppendSibling(B); } -type_list_or_void ::= VOID. -type_list_or_void ::= type_list. +type_list_or_void(X) ::= VOID. { X = NULL; } +type_list_or_void(X) ::= type_list(A). { X = A; } -%type array_size{ZCC_Expression *} array_size(X) ::= LBRACKET opt_expr(A) RBRACKET. { if (A == NULL) { NEW_AST_NODE(Expression,nil); + nil->Operation = PEX_Nil; X = nil; } else @@ -436,6 +441,7 @@ array_size(X) ::= array_size(A) LBRACKET opt_expr(B) RBRACKET. if (B == NULL) { NEW_AST_NODE(Expression,nil); + nil->Operation = PEX_Nil; A->AppendSibling(nil); } else @@ -459,23 +465,15 @@ variables_or_function ::= error SEMICOLON. %type variable_name{ZCC_VarName *} %type variable_list{ZCC_VarName *} +%type decl_flags{int} variable_name(X) ::= IDENTIFIER(A). { NEW_AST_NODE(VarName,var); var->Name = ENamedName(A.Int); - var->bIsArray = false; - var->ArraySize = 0; - X = var; -} -variable_name(X) ::= IDENTIFIER(A) array_size(B). -{ - NEW_AST_NODE(VarName,var); - var->Name = ENamedName(A.Int); - var->bIsArray = false; - var->ArraySize = B; X = var; } + variable_list(X) ::= variable_name(A). { X = A; @@ -486,16 +484,17 @@ variable_list(X) ::= variable_list(A) COMMA variable_name(B). X = A; } -decl_flags ::= . -decl_flags ::= decl_flags NATIVE. -decl_flags ::= decl_flags STATIC. -decl_flags ::= decl_flags PRIVATE. -decl_flags ::= decl_flags PROTECTED. -decl_flags ::= decl_flags LATENT. -decl_flags ::= decl_flags FINAL. -decl_flags ::= decl_flags META. -decl_flags ::= decl_flags ACTION. -decl_flags ::= decl_flags DEPRECATED LPAREN string_constant RPAREN. +decl_flags(X) ::= . { X = 0; } +decl_flags(X) ::= decl_flags(A) NATIVE. { X = A | ZCC_Native; } +decl_flags(X) ::= decl_flags(A) STATIC. { X = A | ZCC_Static; } +decl_flags(X) ::= decl_flags(A) PRIVATE. { X = A | ZCC_Private; } +decl_flags(X) ::= decl_flags(A) PROTECTED. { X = A | ZCC_Protected; } +decl_flags(X) ::= decl_flags(A) LATENT. { X = A | ZCC_Latent; } +decl_flags(X) ::= decl_flags(A) FINAL. { X = A | ZCC_Final; } +decl_flags(X) ::= decl_flags(A) META. { X = A | ZCC_Meta; } +decl_flags(X) ::= decl_flags(A) ACTION. { X = A | ZCC_Action; } +decl_flags(X) ::= decl_flags(A) READONLY. { X = A | ZCC_ReadOnly; } +decl_flags(X) ::= decl_flags(A) DEPRECATED. { X = A | ZCC_Deprecated; } func_const ::= . func_const ::= CONST. @@ -503,22 +502,40 @@ func_const ::= CONST. opt_func_body ::= SEMICOLON. opt_func_body ::= function_body. -func_params ::= . /* empty */ -func_params ::= VOID. -func_params ::= func_param_list. +%type func_params {ZCC_FuncParamDecl *} +%type func_param_list {ZCC_FuncParamDecl *} +%type func_param {ZCC_FuncParamDecl *} +%type func_param_flags {int} -func_param_list ::= func_param. -func_param_list ::= func_param COMMA func_param_list. +func_params(X) ::= . /* empty */ { X = NULL; } +func_params(X) ::= VOID. { X = NULL; } +func_params(X) ::= func_param_list(A). { X = A; } -func_param ::= func_param_flags type variable_name. +func_param_list(X) ::= func_param(A). { X = A; } +func_param_list(X) ::= func_param(A) COMMA func_param_list(B). { X = A; A->AppendSibling(B); } -func_param_flags ::= . -func_param_flags ::= func_param_flags IN. -func_param_flags ::= func_param_flags OUT. -func_param_flags ::= func_param_flags OPTIONAL. +func_param(X) ::= func_param_flags(A) type(B) IDENTIFIER(C). +{ + NEW_AST_NODE(FuncParamDecl,parm); + parm->Type = B; + parm->Name = C.Name(); + parm->Flags = A; + X = parm; +} + +func_param_flags(X) ::= . { X = 0; } +func_param_flags(X) ::= func_param_flags(A) IN. { X = A | ZCC_In; } +func_param_flags(X) ::= func_param_flags(A) OUT. { X = A | ZCC_Out; } +func_param_flags(X) ::= func_param_flags(A) OPTIONAL. { X = A | ZCC_Optional; } /* Like UnrealScript, a constant's type is implied by its value's type. */ -const_def ::= CONST IDENTIFIER EQ expr SEMICOLON. +const_def(X) ::= CONST IDENTIFIER(A) EQ expr(B) SEMICOLON. +{ + NEW_AST_NODE(ConstantDef,def); + def->Name = A.Name(); + def->Value = B; + X = def; +} /************ Expressions ************/ diff --git a/src/zscript/zcc_parser.cpp b/src/zscript/zcc_parser.cpp index eab49046a..69e501d10 100644 --- a/src/zscript/zcc_parser.cpp +++ b/src/zscript/zcc_parser.cpp @@ -76,6 +76,7 @@ static void InitTokenMap() TOKENDEF(TK_Final, ZCC_FINAL); TOKENDEF(TK_Meta, ZCC_META); TOKENDEF(TK_Deprecated, ZCC_DEPRECATED); + TOKENDEF(TK_ReadOnly, ZCC_READONLY); TOKENDEF('{', ZCC_LBRACE); TOKENDEF('}', ZCC_RBRACE); TOKENDEF(TK_Struct, ZCC_STRUCT); diff --git a/src/zscript/zcc_parser.h b/src/zscript/zcc_parser.h index ce340f5db..f14261c28 100644 --- a/src/zscript/zcc_parser.h +++ b/src/zscript/zcc_parser.h @@ -18,6 +18,31 @@ union ZCCToken ENamedName Name() { return ENamedName(Int); } }; +// Variable / Function modifiers +enum +{ + ZCC_Native = 1 << 0, + ZCC_Static = 1 << 1, + ZCC_Private = 1 << 2, + ZCC_Protected = 1 << 3, + ZCC_Latent = 1 << 4, + ZCC_Final = 1 << 5, + ZCC_Meta = 1 << 6, + ZCC_Action = 1 << 7, + ZCC_Deprecated = 1 << 8, + ZCC_ReadOnly = 1 << 9, +}; + +// Function parameter modifiers +enum +{ + ZCC_In = 1 << 0, + ZCC_Out = 1 << 1, + ZCC_Optional = 1 << 2, +}; + + + // Syntax tree structures. enum EZCCTreeNodeType { @@ -64,6 +89,8 @@ enum EZCCTreeNodeType AST_CaseStmt, AST_AssignStmt, AST_LocalVarStmt, + AST_FuncParamDecl, + AST_ConstantDef, }; enum EZCCIntType @@ -79,6 +106,8 @@ enum EZCCIntType enum EZCCExprType { + PEX_Nil, + PEX_ID, PEX_Super, PEX_Self, @@ -254,15 +283,12 @@ struct ZCC_StateLine : ZCC_StatePart struct ZCC_VarName : ZCC_TreeNode { - bool bIsArray; - ZCC_Expression *ArraySize; ENamedName Name; }; struct ZCC_Type : ZCC_TreeNode { - BITFIELD bIsArray:1; - ZCC_Expression *ArraySize; + ZCC_Expression *ArraySize; // NULL if not an array }; struct ZCC_BasicType : ZCC_Type @@ -414,3 +440,16 @@ struct ZCC_LocalVarStmt : ZCC_Statement ZCC_VarName *Vars; ZCC_Expression *Inits; }; + +struct ZCC_FuncParamDecl : ZCC_TreeNode +{ + ZCC_Type *Type; + ENamedName Name; + int Flags; +}; + +struct ZCC_ConstantDef : ZCC_TreeNode +{ + ENamedName Name; + ZCC_Expression *Value; +};