278 lines
9.2 KiB
C
278 lines
9.2 KiB
C
LC_FUNCTION LC_AST *LC_CopyAST(LC_Arena *arena, LC_AST *n) {
|
|
if (n == NULL) return NULL;
|
|
|
|
LC_AST *result = LC_PushStruct(arena, LC_AST);
|
|
result->kind = n->kind;
|
|
result->id = ++L->ast_count;
|
|
result->notes = LC_CopyAST(arena, n->notes);
|
|
result->pos = n->pos;
|
|
|
|
switch (n->kind) {
|
|
case LC_ASTKind_File: {
|
|
result->afile.x = n->afile.x;
|
|
|
|
LC_ASTFor(it, n->afile.fimport) {
|
|
LC_AST *it_copy = LC_CopyAST(arena, it);
|
|
LC_DLLAdd(result->afile.fimport, result->afile.limport, it_copy);
|
|
}
|
|
LC_ASTFor(it, n->afile.fdecl) {
|
|
LC_AST *it_copy = LC_CopyAST(arena, it);
|
|
LC_DLLAdd(result->afile.fdecl, result->afile.ldecl, it_copy);
|
|
}
|
|
} break;
|
|
|
|
case LC_ASTKind_DeclProc: {
|
|
result->dbase.name = n->dbase.name;
|
|
result->dproc.body = LC_CopyAST(arena, n->dproc.body);
|
|
result->dproc.type = LC_CopyAST(arena, n->dproc.type);
|
|
} break;
|
|
|
|
case LC_ASTKind_NoteList: {
|
|
LC_ASTFor(it, n->anote_list.first) {
|
|
LC_AST *it_copy = LC_CopyAST(arena, it);
|
|
LC_DLLAdd(result->anote_list.first, result->anote_list.last, it_copy);
|
|
}
|
|
} break;
|
|
|
|
case LC_ASTKind_TypespecAggMem:
|
|
case LC_ASTKind_TypespecProcArg: {
|
|
result->tproc_arg.name = n->tproc_arg.name;
|
|
result->tproc_arg.type = LC_CopyAST(arena, n->tproc_arg.type);
|
|
result->tproc_arg.expr = LC_CopyAST(arena, n->tproc_arg.expr);
|
|
} break;
|
|
|
|
case LC_ASTKind_ExprNote: {
|
|
result->enote.expr = LC_CopyAST(arena, n->enote.expr);
|
|
} break;
|
|
|
|
case LC_ASTKind_StmtSwitch: {
|
|
LC_ASTFor(it, n->sswitch.first) {
|
|
LC_AST *it_copy = LC_CopyAST(arena, it);
|
|
LC_DLLAdd(result->sswitch.first, result->sswitch.last, it_copy);
|
|
}
|
|
result->sswitch.total_switch_case_count = n->sswitch.total_switch_case_count;
|
|
result->sswitch.expr = LC_CopyAST(arena, n->sswitch.expr);
|
|
} break;
|
|
|
|
case LC_ASTKind_StmtSwitchCase: {
|
|
LC_ASTFor(it, n->scase.first) {
|
|
LC_AST *it_copy = LC_CopyAST(arena, it);
|
|
LC_DLLAdd(result->scase.first, result->scase.last, it_copy);
|
|
}
|
|
result->scase.body = LC_CopyAST(arena, n->scase.body);
|
|
} break;
|
|
|
|
case LC_ASTKind_StmtSwitchDefault: {
|
|
LC_ASTFor(it, n->scase.first) {
|
|
LC_AST *it_copy = LC_CopyAST(arena, it);
|
|
LC_DLLAdd(result->scase.first, result->scase.last, it_copy);
|
|
}
|
|
result->scase.body = LC_CopyAST(arena, n->scase.body);
|
|
} break;
|
|
|
|
case LC_ASTKind_StmtIf: {
|
|
LC_ASTFor(it, n->sif.first) {
|
|
LC_AST *it_copy = LC_CopyAST(arena, it);
|
|
LC_DLLAdd(result->sswitch.first, result->sswitch.last, it_copy);
|
|
}
|
|
result->sif.expr = LC_CopyAST(arena, n->sif.expr);
|
|
result->sif.body = LC_CopyAST(arena, n->sif.body);
|
|
} break;
|
|
|
|
case LC_ASTKind_StmtElse:
|
|
case LC_ASTKind_StmtElseIf: {
|
|
result->sif.expr = LC_CopyAST(arena, n->sif.expr);
|
|
result->sif.body = LC_CopyAST(arena, n->sif.body);
|
|
} break;
|
|
|
|
case LC_ASTKind_GlobImport: {
|
|
result->gimport.name = n->gimport.name;
|
|
result->gimport.path = n->gimport.path;
|
|
} break;
|
|
|
|
case LC_ASTKind_DeclNote: {
|
|
result->dnote.expr = LC_CopyAST(arena, n->dnote.expr);
|
|
} break;
|
|
|
|
case LC_ASTKind_DeclUnion:
|
|
case LC_ASTKind_DeclStruct: {
|
|
result->dbase.name = n->dbase.name;
|
|
LC_ASTFor(it, n->dagg.first) {
|
|
LC_AST *it_copy = LC_CopyAST(arena, it);
|
|
LC_DLLAdd(result->dagg.first, result->dagg.last, it_copy);
|
|
}
|
|
} break;
|
|
|
|
case LC_ASTKind_DeclVar: {
|
|
result->dbase.name = n->dbase.name;
|
|
result->dvar.type = LC_CopyAST(arena, n->dvar.type);
|
|
result->dvar.expr = LC_CopyAST(arena, n->dvar.expr);
|
|
} break;
|
|
|
|
case LC_ASTKind_DeclConst: {
|
|
result->dbase.name = n->dbase.name;
|
|
result->dconst.expr = LC_CopyAST(arena, n->dconst.expr);
|
|
} break;
|
|
|
|
case LC_ASTKind_DeclTypedef: {
|
|
result->dbase.name = n->dbase.name;
|
|
result->dtypedef.type = LC_CopyAST(arena, n->dtypedef.type);
|
|
} break;
|
|
|
|
case LC_ASTKind_ExprField:
|
|
case LC_ASTKind_TypespecField: {
|
|
result->efield.left = LC_CopyAST(arena, n->efield.left);
|
|
result->efield.right = n->efield.right;
|
|
} break;
|
|
|
|
case LC_ASTKind_TypespecIdent: {
|
|
result->eident.name = n->eident.name;
|
|
} break;
|
|
|
|
case LC_ASTKind_TypespecPointer: {
|
|
result->tpointer.base = LC_CopyAST(arena, n->tpointer.base);
|
|
} break;
|
|
|
|
case LC_ASTKind_TypespecArray: {
|
|
result->tarray.base = LC_CopyAST(arena, n->tarray.base);
|
|
result->tarray.index = LC_CopyAST(arena, n->tarray.index);
|
|
} break;
|
|
|
|
case LC_ASTKind_TypespecProc: {
|
|
LC_ASTFor(it, n->tproc.first) {
|
|
LC_AST *it_copy = LC_CopyAST(arena, it);
|
|
LC_DLLAdd(result->tproc.first, result->tproc.last, it_copy);
|
|
}
|
|
result->tproc.ret = LC_CopyAST(arena, n->tproc.ret);
|
|
result->tproc.vargs = n->tproc.vargs;
|
|
} break;
|
|
|
|
case LC_ASTKind_StmtBlock: {
|
|
LC_ASTFor(it, n->sblock.first) {
|
|
LC_AST *it_copy = LC_CopyAST(arena, it);
|
|
LC_DLLAdd(result->sblock.first, result->sblock.last, it_copy);
|
|
|
|
if (it_copy->kind == LC_ASTKind_StmtDefer) {
|
|
LC_SLLStackAddMod(result->sblock.first_defer, it_copy, sdefer.next);
|
|
}
|
|
}
|
|
if (n->sblock.first_defer) {
|
|
LC_ASSERT(result, result->sblock.first_defer);
|
|
}
|
|
result->sblock.kind = n->sblock.kind;
|
|
result->sblock.name = n->sblock.name;
|
|
} break;
|
|
|
|
case LC_ASTKind_StmtNote: {
|
|
result->snote.expr = LC_CopyAST(arena, n->snote.expr);
|
|
} break;
|
|
|
|
case LC_ASTKind_StmtReturn: {
|
|
result->sreturn.expr = LC_CopyAST(arena, n->sreturn.expr);
|
|
} break;
|
|
|
|
case LC_ASTKind_StmtBreak: {
|
|
result->sbreak.name = n->sbreak.name;
|
|
} break;
|
|
|
|
case LC_ASTKind_StmtContinue: {
|
|
result->scontinue.name = n->scontinue.name;
|
|
} break;
|
|
|
|
case LC_ASTKind_StmtDefer: {
|
|
result->sdefer.body = LC_CopyAST(arena, n->sdefer.body);
|
|
} break;
|
|
|
|
case LC_ASTKind_StmtFor: {
|
|
result->sfor.init = LC_CopyAST(arena, n->sfor.init);
|
|
result->sfor.cond = LC_CopyAST(arena, n->sfor.cond);
|
|
result->sfor.inc = LC_CopyAST(arena, n->sfor.inc);
|
|
result->sfor.body = LC_CopyAST(arena, n->sfor.body);
|
|
} break;
|
|
|
|
case LC_ASTKind_StmtAssign: {
|
|
result->sassign.op = n->sassign.op;
|
|
result->sassign.left = LC_CopyAST(arena, n->sassign.left);
|
|
result->sassign.right = LC_CopyAST(arena, n->sassign.right);
|
|
} break;
|
|
|
|
case LC_ASTKind_StmtExpr: {
|
|
result->sexpr.expr = LC_CopyAST(arena, n->sexpr.expr);
|
|
} break;
|
|
|
|
case LC_ASTKind_StmtVar: {
|
|
result->svar.type = LC_CopyAST(arena, n->svar.type);
|
|
result->svar.expr = LC_CopyAST(arena, n->svar.expr);
|
|
result->svar.name = n->svar.name;
|
|
} break;
|
|
|
|
case LC_ASTKind_StmtConst: {
|
|
result->sconst.expr = LC_CopyAST(arena, n->sconst.expr);
|
|
result->sconst.name = n->sconst.name;
|
|
} break;
|
|
|
|
case LC_ASTKind_ExprIdent: {
|
|
result->eident.name = n->eident.name;
|
|
} break;
|
|
|
|
case LC_ASTKind_ExprBool:
|
|
case LC_ASTKind_ExprFloat:
|
|
case LC_ASTKind_ExprInt:
|
|
case LC_ASTKind_ExprString: {
|
|
result->eatom = n->eatom;
|
|
} break;
|
|
|
|
case LC_ASTKind_ExprType: {
|
|
result->etype.type = LC_CopyAST(arena, n->etype.type);
|
|
} break;
|
|
|
|
case LC_ASTKind_ExprAddPtr:
|
|
case LC_ASTKind_ExprBinary: {
|
|
result->ebinary.op = n->ebinary.op;
|
|
result->ebinary.left = LC_CopyAST(arena, n->ebinary.left);
|
|
result->ebinary.right = LC_CopyAST(arena, n->ebinary.right);
|
|
} break;
|
|
|
|
case LC_ASTKind_ExprGetPointerOfValue:
|
|
case LC_ASTKind_ExprGetValueOfPointer:
|
|
case LC_ASTKind_ExprUnary: {
|
|
result->eunary.op = n->eunary.op;
|
|
result->eunary.expr = LC_CopyAST(arena, n->eunary.expr);
|
|
} break;
|
|
|
|
case LC_ASTKind_ExprCompoundItem:
|
|
case LC_ASTKind_ExprCallItem: {
|
|
result->ecompo_item.name = n->ecompo_item.name;
|
|
result->ecompo_item.index = LC_CopyAST(arena, n->ecompo_item.index);
|
|
result->ecompo_item.expr = LC_CopyAST(arena, n->ecompo_item.expr);
|
|
} break;
|
|
|
|
case LC_ASTKind_ExprBuiltin:
|
|
case LC_ASTKind_Note:
|
|
case LC_ASTKind_ExprCall:
|
|
case LC_ASTKind_ExprCompound: {
|
|
LC_ASTFor(it, n->ecompo.first) {
|
|
LC_AST *it_copy = LC_CopyAST(arena, it);
|
|
LC_DLLAdd(result->ecompo.first, result->ecompo.last, it_copy);
|
|
}
|
|
|
|
result->ecompo.size = n->ecompo.size;
|
|
result->ecompo.name = LC_CopyAST(arena, n->ecompo.name);
|
|
} break;
|
|
|
|
case LC_ASTKind_ExprCast: {
|
|
result->ecast.type = LC_CopyAST(arena, n->ecast.type);
|
|
result->ecast.expr = LC_CopyAST(arena, n->ecast.expr);
|
|
} break;
|
|
|
|
case LC_ASTKind_ExprIndex: {
|
|
result->eindex.index = LC_CopyAST(arena, n->eindex.index);
|
|
result->eindex.base = LC_CopyAST(arena, n->eindex.base);
|
|
} break;
|
|
|
|
default: LC_ReportASTError(n, "internal compiler error: failed to LC_CopyAST, got invalid ast kind: %s", LC_ASTKindToString(n->kind));
|
|
}
|
|
|
|
return result;
|
|
}
|