summaryrefslogtreecommitdiffstats
path: root/scilab/modules/ast/src/cpp/analysis/VisitAssignExp.cpp
blob: 73317fdfe992aa9c7c5a80486fe524544268daba (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
/*
 *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
 *  Copyright (C) 2015 - Scilab Enterprises - Calixte DENIZET
 *
 * Copyright (C) 2012 - 2016 - Scilab Enterprises
 *
 * This file is hereby licensed under the terms of the GNU GPL v2.0,
 * pursuant to article 5.3.4 of the CeCILL v.2.1.
 * This file was originally licensed under the terms of the CeCILL v2.1,
 * and continues to be available under such terms.
 * For more information, see the COPYING file which you should have received
 * along with this program.
 *
 */

#include "AnalysisVisitor.hxx"

namespace analysis
{

void AnalysisVisitor::visit(ast::AssignExp & e)
{
    logger.log(L"AssignExp", e.getLocation());
    if (e.getLeftExp().isSimpleVar()) // A = ...
    {
        ast::SimpleVar & var = static_cast<ast::SimpleVar &>(e.getLeftExp());
        const symbol::Symbol & sym = var.getSymbol();

        if (e.getRightExp().isSimpleVar())
        {
            // We have A = B (so the data associated to b is shared with a)
            const symbol::Symbol & symR = static_cast<ast::SimpleVar &>(e.getRightExp()).getSymbol();
            Info & info = getSymInfo(symR);
            const TIType & Rtype = info.getType();
            Result & resL = e.getLeftExp().getDecorator().setResult(Rtype);
            resL.setConstant(info.getConstant());
            resL.setRange(info.getRange());
            Result & resR = e.getRightExp().getDecorator().setResult(Rtype);
            resR.setConstant(info.getConstant());
            resR.setRange(info.getRange());
            getDM().share(sym, symR, Rtype, resR.isAnInt(), &e);
        }
        else
        {
            // apply the ConstantVisitor
            cv.setLHS(1);
            e.getRightExp().accept(cv);

            if (e.getRightExp().isCallExp()) // A = foo(...)
            {
                visit(static_cast<ast::CallExp &>(e.getRightExp()), /* LHS */ 1);
            }
            else // A = 1 + 2
            {
                e.getRightExp().accept(*this);
            }

            Result & RR = getResult();
            var.getDecorator().res = RR;
            Info & info = getDM().define(sym, RR.getType(), RR.isAnInt(), &e);
            info.getConstant() = RR.getConstant();
            e.getDecorator().safe = true;

            // Don't remove temp: because the value is transfered to LHS
            getDM().releaseTmp(RR.getTempId(), nullptr);//&e.getRightExp());
        }
    }
    else if (e.getLeftExp().isCallExp()) // A(12) = ...
    {
        // apply the ConstantVisitor
        cv.setLHS(1);
        e.getRightExp().accept(cv);

        ast::CallExp & ce = static_cast<ast::CallExp &>(e.getLeftExp());
        if (ce.getName().isSimpleVar())
        {
            const symbol::Symbol & symL = static_cast<ast::SimpleVar &>(ce.getName()).getSymbol();
            e.getRightExp().accept(*this);
            Result & RR = e.getRightExp().getDecorator().getResult();
            ce.getDecorator().res = RR;
            Info & info = getDM().write(symL, RR.getType(), &ce.getName());
            ce.getName().getDecorator().setResult(info.type);
            if (analyzeIndices(info.type, ce))
            {
                e.getDecorator().safe = (RR.getType() == getResult().getType());
            }
            getDM().releaseTmp(RR.getTempId(), &e.getRightExp());
        }
    }
    else if (e.getLeftExp().isAssignListExp()) // [A, B] = ...
    {
        ast::AssignListExp & ale = static_cast<ast::AssignListExp &>(e.getLeftExp());
        if (e.getRightExp().isCallExp())
        {
            const ast::exps_t & exps = ale.getExps();

            // apply the ConstantVisitor
            cv.setLHS(exps.size());
            e.getRightExp().accept(cv);

            visit(static_cast<ast::CallExp &>(e.getRightExp()), /* LHS */ exps.size());
            std::vector<Result>::iterator j = multipleLHS.begin();
            for (const auto exp : exps)
            {
                // TODO: handle fields...
                if (exp->isSimpleVar() && j != multipleLHS.end())
                {
                    ast::SimpleVar & var = *static_cast<ast::SimpleVar *>(exp);
                    const symbol::Symbol & sym = var.getSymbol();
                    Info & info = getDM().define(sym, j->getType(), j->isAnInt(), exp);
                    info.setConstant(j->getConstant());
                    var.getDecorator().res = *j;
                    ++j;
                }
            }
        }
    }
}
}