Allow access to the numeric properties.

- Identifiers can now evaluate to type references.
- The dot operator can now find symbols in type references.
This commit is contained in:
Randy Heit 2013-10-29 21:55:32 -05:00
parent e7616ec0bd
commit 39d7fa0605
6 changed files with 112 additions and 5 deletions

View file

@ -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,

View file

@ -230,6 +230,10 @@ ZCC_Expression *ZCCCompiler::Simplify(ZCC_Expression *root)
{
return IdentifyIdentifier(static_cast<ZCC_ExprID *>(root));
}
else if (root->Operation == PEX_MemberAccess)
{
return SimplifyMemberAccess(static_cast<ZCC_ExprMemberAccess *>(root));
}
else if (IsUnaryOp(root->Operation))
{
return SimplifyUnary(static_cast<ZCC_ExprUnary *>(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<ZCC_ExprTypeRef *>(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<PSymbolConst *>(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<PSymbolConst *>(sym), source);
}
else if (sym->IsKindOf(RUNTIME_CLASS(PSymbolType)))
{
return NodeFromSymbolType(static_cast<PSymbolType *>(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<ZCC_ExprConstant *>(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<ZCC_ExprTypeRef *>(AST.InitNode(sizeof(*ref), AST_ExprTypeRef, idnode));
ref->Operation = PEX_TypeRef;
ref->RefType = sym->Type;
ref->Type = NewClassPointer(RUNTIME_CLASS(PType));
return ref;
}

View file

@ -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, ...);

View file

@ -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,
};

View file

@ -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)

View file

@ -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