Esempio n. 1
0
        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);
        }
Esempio n. 2
0
        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);
            }
        }