Added mixins for classes.

This commit is contained in:
Chronos Ouroboros 2019-11-01 18:33:15 -03:00
commit e63b6d494a
7 changed files with 206 additions and 0 deletions

View file

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