------------------------------------------------------------------------------
--                                                                          --
--                           ASIStint COMPONENTS                             --
--                                                                          --
--                    A S I S T I N T . E V A L U A T E                     --
--                                                                          --
--                                 B o d y                                  --
--                                                                          --
--            Copyright (c) 1997, Free Software Foundation, Inc.            --
--                                                                          --
-- ASIStint is free software; you can redistribute  it  and/or  modify  it  --
-- under terms of the GNU General Public License  as published by the  Free --
-- Software Foundation;  either version 2,  or  (at your option)  any later --
-- version.  ASIStint  is distributed  in the hope  that it will be useful, --
-- but  WITHOUT  ANY  WARRANTY;  without even the implied warranty of  MER- --
-- CHANTABILITY or  FITNESS FOR A PARTICULAR PURPOSE.  See the  GNU General --
-- Public License for more details.  You should have received a copy of the --
-- GNU General Public License  distributed with ASIStint; see file COPYING. --
-- If not, write to the  Free  Software  Foundation,  59 Temple Place Suite --
-- 330, Boston, MA 02111-1307, USA.                                         --
--                                                                          --
-- ASIStint  was  originally  developed  by  the  ASIS-for-GNAT team at the --
-- Software Engineering  Laboratory  of  the  Swiss  Federal  Institute  of --
-- Technology (LGL-EPFL) in Lausanne, Switzerland, in cooperation with  the --
-- Scientific  Research  Computer  Center  of Moscow State University (SRCC --
-- MSU), Russia.                                                            --
--                                                                          --
-- This work was supported by a  grant  from  the  Swiss  National  Science --
-- Foundation, no 7SUPJ048247, funding a project entitled  "Development  of --
-- ASIS for GNAT with industry quality".                                    --
------------------------------------------------------------------------------

with Asis; use Asis;
with ASIStint.Call;     use ASIStint.Call;
with ASIStint.Common;   use ASIStint.Common;
with ASIStint.Get;      use ASIStint.Get;
with ASIStint.S_Parser; use ASIStint.S_Parser;
with ASIStint.Table;    use ASIStint.Table;
with ASIStint.XTable;   use ASIStint.XTable;

with FuncEnum; use FuncEnum;

package body ASIStint.Evaluate is

------------------------------------------------------------------------------
-- ASIStint expressions evaluation
------------------------------------------------------------------------------

  function Evaluate_Node (NPtr: Node_Position) return Query_Result is

    QR: Query_Result;
    VI: Var_Info;
    NPtr1, NPtrP: Node_Position;

  begin

      case CurStat.Tree(NPtr).NType is

      when NT_BOOLEAN     =>
        return (Par_Boolean, Boolean'Val(CurStat.Tree(NPtr).IValue));

      when NT_INTEGER     =>
        return (Par_Integer, Integer'Wide_Value(CurStat.Tree(NPtr).SValue.All));

      when NT_STRING      =>
        return (Par_String, Save_String(CurStat.Tree(NPtr).SValue.All));

      when NT_VARIABLE    =>
        VI := Get_Var(CurTable, CurStat.Tree(NPtr).SValue.All);
        if VI /= Var_Unknown
          then
            return Get_Var_Value(VI);
          else
            declare
              PS: Parameter_Set;
            begin
              return Call_ASIStint_Function (CurStat.Tree(NPtr).SValue.All, PS);
            end;
        end if;

      when NT_FUNCTION =>
        VI := Get_Var(CurTable, CurStat.Tree(NPtr).SValue.All);

        if VI /= Var_Unknown

          then -- An indexing
            if VI.VType /= Par_ElemList and VI.VType /= Par_CUnitList then
              Error(ERR_BADVARTYPE);
            end if;

            NPtr1 := CurStat.Tree(NPtr).NValue;
            NPtr1 := CurStat.Tree(NPtr1).NValue;
            if CurStat.Tree(NPtr1).Next_Node /= 0
              then
                Error(ERR_BADLISTELEM);
              end if;

            declare
              QR: Query_Result := Evaluate_Node(NPtr1);
            begin
              if QR.RType /= Par_Integer
                then
                  Error(ERR_BADLISTELEM);
              end if;

              if  VI.VType = Par_ElemList
                then
                  return (Par_Element, ATIElemList(VI.IValue).All(QR.I));
                else
                  return (Par_CUnit, ATICUnitList(VI.IValue).All(QR.I));
              end if;
            exception
              when CONSTRAINT_ERROR =>
                Error(ERR_NOTINRANGE);
            end;

          else -- A query call
            declare
              PS : Parameter_Set;
            begin
              -- Determine syntax
              NPtrP := CurStat.Tree(NPtr).NValue;
              for i in 1..3 loop
                NPtr1 := CurStat.Tree(NPtrP).NValue;
                PS(i) := Evaluate_Node(NPtr1);
                NPtrP := CurStat.Tree(NPtrP).Next_Node;
                exit when NPtrP = 0;
              end loop;
              if NPtrP /= 0 then
                Error(ERR_TOOMANYPARAMS);
              end if;

              return Call_ASIStint_Function(CurStat.Tree(NPtr).SValue.All, PS);
            end;
          end if;

      when others     => Error(ERR_INTERNAL, "Module: Evaluate. ST node: " &
                               Node_Type'Wide_Image(CurStat.Tree(NPtr).NType) );
    end case;

  end Evaluate_Node;

end ASIStint.Evaluate;