Added mixins for classes.
This commit is contained in:
parent
4c7c1138aa
commit
e63b6d494a
7 changed files with 206 additions and 0 deletions
|
|
@ -132,6 +132,8 @@ void ZCCCompiler::ProcessClass(ZCC_Class *cnode, PSymbolTreeNode *treenode)
|
|||
}
|
||||
|
||||
auto node = cnode->Body;
|
||||
auto origNextNode = cnode->Body;
|
||||
ZCC_MixinDef *mixinDef = nullptr;
|
||||
PSymbolTreeNode *childnode;
|
||||
ZCC_Enum *enumType = nullptr;
|
||||
|
||||
|
|
@ -140,6 +142,34 @@ void ZCCCompiler::ProcessClass(ZCC_Class *cnode, PSymbolTreeNode *treenode)
|
|||
{
|
||||
switch (node->NodeType)
|
||||
{
|
||||
case AST_MixinStmt:
|
||||
{
|
||||
auto mixinStmt = static_cast<ZCC_MixinStmt *>(node);
|
||||
for (auto mx : Mixins)
|
||||
{
|
||||
if (mx->mixin->NodeName == mixinStmt->MixinName)
|
||||
{
|
||||
if (mx->mixin->MixinType != ZCC_Mixin_Class)
|
||||
{
|
||||
Error(node, "Mixin %s is not a class mixin.", FName(mixinStmt->MixinName).GetChars());
|
||||
}
|
||||
|
||||
mixinDef = mx->mixin;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (mixinDef == nullptr)
|
||||
{
|
||||
Error(node, "Mixin %s does not exist.", FName(mixinStmt->MixinName).GetChars());
|
||||
break;
|
||||
}
|
||||
|
||||
origNextNode = node->SiblingNext;
|
||||
node = mixinDef->Body;
|
||||
}
|
||||
break;
|
||||
|
||||
case AST_Struct:
|
||||
case AST_ConstantDef:
|
||||
case AST_Enum:
|
||||
|
|
@ -211,11 +241,62 @@ void ZCCCompiler::ProcessClass(ZCC_Class *cnode, PSymbolTreeNode *treenode)
|
|||
assert(0 && "Unhandled AST node type");
|
||||
break;
|
||||
}
|
||||
|
||||
node = node->SiblingNext;
|
||||
|
||||
if (mixinDef != nullptr && node == mixinDef->Body)
|
||||
{
|
||||
node = origNextNode;
|
||||
mixinDef = nullptr;
|
||||
}
|
||||
}
|
||||
while (node != cnode->Body);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// ZCCCompiler :: ProcessMixin
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void ZCCCompiler::ProcessMixin(ZCC_MixinDef *cnode, PSymbolTreeNode *treenode)
|
||||
{
|
||||
ZCC_MixinWork *cls = new ZCC_MixinWork(cnode, treenode);
|
||||
|
||||
Mixins.Push(cls);
|
||||
|
||||
auto node = cnode->Body;
|
||||
|
||||
// Need to check if the class actually has a body.
|
||||
if (node != nullptr) do
|
||||
{
|
||||
if (cnode->MixinType == ZCC_Mixin_Class)
|
||||
{
|
||||
switch (node->NodeType)
|
||||
{
|
||||
case AST_Struct:
|
||||
case AST_ConstantDef:
|
||||
case AST_Enum:
|
||||
case AST_Property:
|
||||
case AST_FlagDef:
|
||||
case AST_VarDeclarator:
|
||||
case AST_EnumTerminator:
|
||||
case AST_States:
|
||||
case AST_FuncDeclarator:
|
||||
case AST_Default:
|
||||
case AST_StaticArrayStatement:
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0 && "Unhandled AST node type");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
node = node->SiblingNext;
|
||||
} while (node != cnode->Body);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// ZCCCompiler :: ProcessStruct
|
||||
|
|
@ -301,6 +382,28 @@ ZCCCompiler::ZCCCompiler(ZCC_AST &ast, DObject *_outer, PSymbolTable &_symbols,
|
|||
{
|
||||
ZCC_TreeNode *node = ast.TopNode;
|
||||
PSymbolTreeNode *tnode;
|
||||
|
||||
// [pbeta] Mixins must be processed before everything else.
|
||||
do
|
||||
{
|
||||
switch (node->NodeType)
|
||||
{
|
||||
case AST_MixinDef:
|
||||
if ((tnode = AddTreeNode(static_cast<ZCC_NamedNode *>(node)->NodeName, node, GlobalTreeNodes)))
|
||||
{
|
||||
switch (node->NodeType)
|
||||
{
|
||||
case AST_MixinDef:
|
||||
ProcessMixin(static_cast<ZCC_MixinDef *>(node), tnode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
node = node->SiblingNext;
|
||||
} while (node != ast.TopNode);
|
||||
|
||||
node = ast.TopNode;
|
||||
PType *enumType = nullptr;
|
||||
ZCC_Enum *zenumType = nullptr;
|
||||
|
||||
|
|
@ -308,6 +411,10 @@ ZCCCompiler::ZCCCompiler(ZCC_AST &ast, DObject *_outer, PSymbolTable &_symbols,
|
|||
{
|
||||
switch (node->NodeType)
|
||||
{
|
||||
case AST_MixinDef:
|
||||
// [pbeta] We already processed mixins, ignore them here.
|
||||
break;
|
||||
|
||||
case AST_Class:
|
||||
// a class extension should not check the tree node symbols.
|
||||
if (static_cast<ZCC_Class *>(node)->Flags == ZCC_Extension)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue