From 39d7fa0605d7063e2f34afc77e1b0ce26d13ec87 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Tue, 29 Oct 2013 21:55:32 -0500 Subject: [PATCH] Allow access to the numeric properties. - Identifiers can now evaluate to type references. - The dot operator can now find symbols in type references. --- src/zscript/ast.cpp | 20 +++++++++ src/zscript/zcc_compile.cpp | 83 +++++++++++++++++++++++++++++++++++-- src/zscript/zcc_compile.h | 5 ++- src/zscript/zcc_errors.h | 2 + src/zscript/zcc_exprlist.h | 1 + src/zscript/zcc_parser.h | 6 +++ 6 files changed, 112 insertions(+), 5 deletions(-) diff --git a/src/zscript/ast.cpp b/src/zscript/ast.cpp index 7424e9aae1..bba089a301 100644 --- a/src/zscript/ast.cpp +++ b/src/zscript/ast.cpp @@ -471,6 +471,25 @@ static void PrintExprID(FLispString &out, ZCC_TreeNode *node) out.Close(); } +static void PrintExprTypeRef(FLispString &out, ZCC_TreeNode *node) +{ + ZCC_ExprTypeRef *enode = (ZCC_ExprTypeRef *)node; + assert(enode->Operation == PEX_TypeRef); + out.Open("expr-type-ref"); + if (enode->RefType == TypeSInt8) { out.Add("sint8"); } + else if (enode->RefType == TypeUInt8) { out.Add("uint8"); } + else if (enode->RefType == TypeSInt16) { out.Add("sint16"); } + else if (enode->RefType == TypeSInt32) { out.Add("sint32"); } + else if (enode->RefType == TypeFloat32) { out.Add("float32"); } + else if (enode->RefType == TypeFloat64) { out.Add("float64"); } + else if (enode->RefType == TypeString) { out.Add("string"); } + else if (enode->RefType == TypeName) { out.Add("name"); } + else if (enode->RefType == TypeColor) { out.Add("color"); } + else if (enode->RefType == TypeSound) { out.Add("sound"); } + else { out.Add("other"); } + out.Close(); +} + static void PrintExprConstant(FLispString &out, ZCC_TreeNode *node) { ZCC_ExprConstant *enode = (ZCC_ExprConstant *)node; @@ -767,6 +786,7 @@ void (* const TreeNodePrinter[NUM_AST_NODE_TYPES])(FLispString &, ZCC_TreeNode * PrintClassType, PrintExpression, PrintExprID, + PrintExprTypeRef, PrintExprConstant, PrintExprFuncCall, PrintExprMemberAccess, diff --git a/src/zscript/zcc_compile.cpp b/src/zscript/zcc_compile.cpp index ce02c8e826..b6ff67a47e 100644 --- a/src/zscript/zcc_compile.cpp +++ b/src/zscript/zcc_compile.cpp @@ -230,6 +230,10 @@ ZCC_Expression *ZCCCompiler::Simplify(ZCC_Expression *root) { return IdentifyIdentifier(static_cast(root)); } + else if (root->Operation == PEX_MemberAccess) + { + return SimplifyMemberAccess(static_cast(root)); + } else if (IsUnaryOp(root->Operation)) { return SimplifyUnary(static_cast(root)); @@ -286,6 +290,40 @@ ZCC_Expression *ZCCCompiler::SimplifyBinary(ZCC_ExprBinary *binary) return binary; } +//========================================================================== +// +// ZCCCompiler :: SimplifyMemberAccess +// +//========================================================================== + +ZCC_Expression *ZCCCompiler::SimplifyMemberAccess(ZCC_ExprMemberAccess *dotop) +{ + dotop->Left = Simplify(dotop->Left); + + if (dotop->Left->Operation == PEX_TypeRef) + { // Type refs can be evaluated now. + PType *ref = static_cast(dotop->Left)->RefType; + PSymbol *sym = ref->Symbols.FindSymbol(dotop->Right, true); + if (sym == NULL) + { + Message(dotop, ERR_not_a_member, "'%s' is not a valid member", FName(dotop->Right).GetChars()); + } + else + { + ZCC_Expression *expr = NodeFromSymbol(sym, dotop); + if (expr == NULL) + { + Message(dotop, ERR_bad_symbol, "Unhandled symbol type encountered"); + } + else + { + return expr; + } + } + } + return dotop; +} + //========================================================================== // // ZCCCompiler :: PromoteUnary @@ -387,9 +425,10 @@ ZCC_Expression *ZCCCompiler::IdentifyIdentifier(ZCC_ExprID *idnode) PSymbol *sym; if (NULL != (sym = Symbols.FindSymbol(idnode->Identifier, true))) { - if (sym->IsKindOf(RUNTIME_CLASS(PSymbolConst))) + ZCC_Expression *node = NodeFromSymbol(sym, idnode); + if (node != NULL) { - return NodeFromSymbolConst(static_cast(sym), idnode); + return node; } } else @@ -425,13 +464,32 @@ ZCC_Expression *ZCCCompiler::IdentifyIdentifier(ZCC_ExprID *idnode) //========================================================================== // -// ZCCCompiler :: NodeFromSymoblConst +// ZCCCompiler :: NodeFromSymbol +// +//========================================================================== + +ZCC_Expression *ZCCCompiler::NodeFromSymbol(PSymbol *sym, ZCC_Expression *source) +{ + if (sym->IsKindOf(RUNTIME_CLASS(PSymbolConst))) + { + return NodeFromSymbolConst(static_cast(sym), source); + } + else if (sym->IsKindOf(RUNTIME_CLASS(PSymbolType))) + { + return NodeFromSymbolType(static_cast(sym), source); + } + return NULL; +} + +//========================================================================== +// +// ZCCCompiler :: NodeFromSymbolConst // // Returns a new AST constant node with the symbol's content. // //========================================================================== -ZCC_ExprConstant *ZCCCompiler::NodeFromSymbolConst(PSymbolConst *sym, ZCC_ExprID *idnode) +ZCC_ExprConstant *ZCCCompiler::NodeFromSymbolConst(PSymbolConst *sym, ZCC_Expression *idnode) { ZCC_ExprConstant *val = static_cast(AST.InitNode(sizeof(*val), AST_ExprConstant, idnode)); val->Operation = PEX_ConstValue; @@ -464,3 +522,20 @@ ZCC_ExprConstant *ZCCCompiler::NodeFromSymbolConst(PSymbolConst *sym, ZCC_ExprID } return val; } + +//========================================================================== +// +// ZCCCompiler :: NodeFromSymbolType +// +// Returns a new AST type ref node with the symbol's content. +// +//========================================================================== + +ZCC_ExprTypeRef *ZCCCompiler::NodeFromSymbolType(PSymbolType *sym, ZCC_Expression *idnode) +{ + ZCC_ExprTypeRef *ref = static_cast(AST.InitNode(sizeof(*ref), AST_ExprTypeRef, idnode)); + ref->Operation = PEX_TypeRef; + ref->RefType = sym->Type; + ref->Type = NewClassPointer(RUNTIME_CLASS(PType)); + return ref; +} diff --git a/src/zscript/zcc_compile.h b/src/zscript/zcc_compile.h index 69311cdee7..a5029ad93c 100644 --- a/src/zscript/zcc_compile.h +++ b/src/zscript/zcc_compile.h @@ -23,6 +23,7 @@ private: ZCC_Expression *Simplify(ZCC_Expression *root); ZCC_Expression *SimplifyUnary(ZCC_ExprUnary *unary); ZCC_Expression *SimplifyBinary(ZCC_ExprBinary *binary); + ZCC_Expression *SimplifyMemberAccess(ZCC_ExprMemberAccess *dotop); ZCC_OpProto *PromoteUnary(EZCCExprType op, ZCC_Expression *&expr); ZCC_OpProto *PromoteBinary(EZCCExprType op, ZCC_Expression *&left, ZCC_Expression *&right); @@ -35,7 +36,9 @@ private: ZCC_Expression *AddCastNode(PType *type, ZCC_Expression *expr); ZCC_Expression *IdentifyIdentifier(ZCC_ExprID *idnode); - ZCC_ExprConstant *NodeFromSymbolConst(PSymbolConst *sym, ZCC_ExprID *idnode); + ZCC_Expression *NodeFromSymbol(PSymbol *sym, ZCC_Expression *source); + ZCC_ExprConstant *NodeFromSymbolConst(PSymbolConst *sym, ZCC_Expression *idnode); + ZCC_ExprTypeRef *NodeFromSymbolType(PSymbolType *sym, ZCC_Expression *idnode); void Message(ZCC_TreeNode *node, EZCCError errnum, const char *msg, ...); diff --git a/src/zscript/zcc_errors.h b/src/zscript/zcc_errors.h index 4b492d02be..7deb5737ec 100644 --- a/src/zscript/zcc_errors.h +++ b/src/zscript/zcc_errors.h @@ -7,4 +7,6 @@ enum EZCCError ERR_symbol_redefinition = 20002 | ZCCERR_ERROR, ERR_original_definition = 20003 | ZCCERR_ERROR, ERR_recursive_definition = 20004 | ZCCERR_ERROR, + ERR_not_a_member = 20005 | ZCCERR_ERROR, + ERR_bad_symbol = 20006 | ZCCERR_ERROR, }; diff --git a/src/zscript/zcc_exprlist.h b/src/zscript/zcc_exprlist.h index 02bb8095f0..cbe78ef094 100644 --- a/src/zscript/zcc_exprlist.h +++ b/src/zscript/zcc_exprlist.h @@ -8,6 +8,7 @@ xx(ConstValue, 0) xx(FuncCall, 0) xx(ArrayAccess, 0) xx(MemberAccess, 0) +xx(TypeRef, 0) xx(PostInc, 1) xx(PostDec, 1) diff --git a/src/zscript/zcc_parser.h b/src/zscript/zcc_parser.h index 03a42a4360..47213b549e 100644 --- a/src/zscript/zcc_parser.h +++ b/src/zscript/zcc_parser.h @@ -67,6 +67,7 @@ enum EZCCTreeNodeType AST_ClassType, AST_Expression, AST_ExprID, + AST_ExprTypeRef, AST_ExprConstant, AST_ExprFuncCall, AST_ExprMemberAccess, @@ -288,6 +289,11 @@ struct ZCC_ExprID : ZCC_Expression ENamedName Identifier; }; +struct ZCC_ExprTypeRef : ZCC_Expression +{ + PType *RefType; +}; + struct ZCC_ExprConstant : ZCC_Expression { union