public SymbolStatusTable Clone() { var result = new SymbolStatusTable(Parent) { Breakable = this.Breakable, Continuable = this.Continuable, }; SymbolStatusTable?p = this; while (p != null) { foreach (var kv in p.mSymbolStatus) { if (!result.mSymbolStatus.ContainsKey(kv.Key)) { result.UpdateSymbolStatus(kv.Key, kv.Value.kind, kv.Value.location); } } p = p.Parent; } return(result); }
private bool Move(CheezType targetType, AstExpression expr, SymbolStatusTable symStatTable, ILocation location) { //if (!(targetType is ReferenceType) && expr.Type is ReferenceType r && !r.TargetType.IsCopy) //{ // ReportError(location, $"Can't move out of reference, the type '{r.TargetType}' can't be copied"); // return false; //} switch (expr) { //case AstTempVarExpr tmp: // { // return Move(targetType, tmp.Expr, symStatTable, location); // } case AstDotExpr dot: { if (dot.Left.Type is EnumType) { Move(targetType, dot.Left, symStatTable, location); return(true); } else if (!dot.Type.IsCopy) { ReportError(location ?? expr, $"Can't move out of '{dot}' because type {dot.Type} is not copy"); return(false); } return(true); } case AstDereferenceExpr d when(!(targetType is ReferenceType) && d.Reference): { return(Move(targetType, d.SubExpression, symStatTable, location)); } case AstIdExpr id: { if (symStatTable.TryGetSymbolStatus(id.Symbol, out var status)) { if (status.kind != SymbolStatus.Kind.initialized) { ReportError(location ?? expr, $"Can't move out of '{id.Name}' because it is {status.kind}", ("Moved here:", status.location)); return(false); } else { // check if type is move or copy var type = (id.Symbol as ITypedSymbol).Type; if (!type.IsCopy) { symStatTable.UpdateSymbolStatus(id.Symbol, SymbolStatus.Kind.moved, expr); } } } else if (id.Symbol is Using use) { return(Move(targetType, use.Expr, symStatTable, id.Location)); } return(true); } //case AstStructValueExpr _: // // TODO: move arguments // break; default: return(true); } }