(********************************************************************)
(*                                                                  *)
(*  pol_act.s7i   Generate code for actions to support poll.        *)
(*  Copyright (C) 1990 - 1994, 2004 - 2014  Thomas Mertes           *)
(*                                                                  *)
(*  This file is part of the Seed7 compiler.                        *)
(*                                                                  *)
(*  This program is free software; you can redistribute it and/or   *)
(*  modify it under the terms of the GNU General Public License as  *)
(*  published by the Free Software Foundation; either version 2 of  *)
(*  the License, or (at your option) any later version.             *)
(*                                                                  *)
(*  This program is distributed in the hope that it will be useful, *)
(*  but WITHOUT ANY WARRANTY; without even the implied warranty of  *)
(*  MERCHANTABILITY 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 along with this program; if not, write to the           *)
(*  Free Software Foundation, Inc., 51 Franklin Street,             *)
(*  Fifth Floor, Boston, MA  02110-1301, USA.                       *)
(*                                                                  *)
(********************************************************************)


const ACTION: POL_ADD_CHECK      is action "POL_ADD_CHECK";
const ACTION: POL_CLEAR          is action "POL_CLEAR";
const ACTION: POL_CPY            is action "POL_CPY";
const ACTION: POL_GET_CHECK      is action "POL_GET_CHECK";
const ACTION: POL_GET_FINDING    is action "POL_GET_FINDING";
const ACTION: POL_HAS_NEXT       is action "POL_HAS_NEXT";
const ACTION: POL_ITER_CHECKS    is action "POL_ITER_CHECKS";
const ACTION: POL_ITER_FINDINGS  is action "POL_ITER_FINDINGS";
const ACTION: POL_NEXT_FILE      is action "POL_NEXT_FILE";
const ACTION: POL_POLL           is action "POL_POLL";
const ACTION: POL_REMOVE_CHECK   is action "POL_REMOVE_CHECK";
const ACTION: POL_VALUE          is action "POL_VALUE";


const proc: pol_prototypes (inout file: c_prog) is func

  begin
    declareExtern(c_prog, "void        polAddCheck (const pollType, const socketType, intType, const genericType);");
    declareExtern(c_prog, "void        polClear (const pollType);");
    declareExtern(c_prog, "void        polCpy (const pollType, const const_pollType);");
    declareExtern(c_prog, "pollType    polCreate (const const_pollType);");
    declareExtern(c_prog, "void        polDestr (const pollType);");
    declareExtern(c_prog, "pollType    polEmpty (void);");
    declareExtern(c_prog, "intType     polGetCheck (const const_pollType, const socketType);");
    declareExtern(c_prog, "intType     polGetFinding (const const_pollType, const socketType);");
    declareExtern(c_prog, "boolType    polHasNext (const pollType);");
    declareExtern(c_prog, "void        polIterChecks (const pollType, intType);");
    declareExtern(c_prog, "void        polIterFindings (const pollType, intType);");
    declareExtern(c_prog, "genericType polNextFile (const pollType, const genericType);");
    declareExtern(c_prog, "void        polPoll (const pollType);");
    declareExtern(c_prog, "void        polRemoveCheck (const pollType, const socketType, intType);");
    declareExtern(c_prog, "pollType    polValue (const const_objRefType);");
  end func;


const proc: process (POL_ADD_CHECK, in reference: function,
    in ref_list: params, inout expr_type: c_expr) is func

  begin
    setDiagnosticLine(c_expr);
    c_expr.expr &:= "polAddCheck(";
    process_expr(params[1], c_expr);
    c_expr.expr &:= ", ";
    process_expr(params[2], c_expr);
    c_expr.expr &:= ", ";
    process_expr(params[3], c_expr);
    c_expr.expr &:= ", (genericType)(";
    process_expr(params[4], c_expr);
    c_expr.expr &:= "));\n";
  end func;


const proc: process (POL_CLEAR, in reference: function,
    in ref_list: params, inout expr_type: c_expr) is func

  begin
    setDiagnosticLine(c_expr);
    c_expr.expr &:= "polClear(";
    process_expr(params[1], c_expr);
    c_expr.expr &:= ");\n";
  end func;


const proc: process (POL_CPY, in reference: function,
    in ref_list: params, inout expr_type: c_expr) is func

  local
    var expr_type: statement is expr_type.value;
    var expr_type: c_param1 is expr_type.value;
    var expr_type: c_param3 is expr_type.value;
  begin
    statement.temp_num := c_expr.temp_num;
    prepareAnyParamTemporarys(params[1], c_param1, statement);
    c_param3.demand := ASSIGN_RESULT;
    prepareAnyParamTemporarys(params[3], c_param3, statement);
    if c_param3.result_expr <> "" then
      statement.temp_decls &:= "pollType new_poll;\n";
      statement.expr &:= "new_poll=";
      statement.expr &:= c_param3.result_expr;
      statement.expr &:= ";\n";
      if isNormalVariable(params[1]) then
        statement.expr &:= "polDestr(";
        statement.expr &:= c_param1.expr;
        statement.expr &:= ");\n";
        statement.expr &:= c_param1.expr;
        statement.expr &:= "=new_poll;\n";
      else
        statement.temp_decls &:= "pollType *poll_ptr=&(";
        statement.temp_decls &:= c_param1.expr;
        statement.temp_decls &:= ");\n";
        statement.expr &:= "polDestr(*poll_ptr);\n";
        statement.expr &:= "*poll_ptr=new_poll;\n";
      end if;
    else
      statement.expr &:= "polCpy(";
      statement.expr &:= c_param1.expr;
      statement.expr &:= ", ";
      statement.expr &:= c_param3.expr;
      statement.expr &:= ");\n";
    end if;
    doLocalDeclsOfStatement(statement, c_expr);
  end func;


const proc: process (POL_GET_CHECK, in reference: function,
    in ref_list: params, inout expr_type: c_expr) is func

  begin
    c_expr.expr &:= "polGetCheck(";
    process_expr(params[1], c_expr);
    c_expr.expr &:= ", ";
    process_expr(params[2], c_expr);
    c_expr.expr &:= ")";
  end func;


const proc: process (POL_GET_FINDING, in reference: function,
    in ref_list: params, inout expr_type: c_expr) is func

  begin
    c_expr.expr &:= "polGetFinding(";
    process_expr(params[1], c_expr);
    c_expr.expr &:= ", ";
    process_expr(params[2], c_expr);
    c_expr.expr &:= ")";
  end func;


const proc: process (POL_HAS_NEXT, in reference: function,
    in ref_list: params, inout expr_type: c_expr) is func

  begin
    c_expr.expr &:= "polHasNext(";
    process_expr(params[1], c_expr);
    c_expr.expr &:= ")";
  end func;


const proc: process (POL_ITER_CHECKS, in reference: function,
    in ref_list: params, inout expr_type: c_expr) is func

  begin
    setDiagnosticLine(c_expr);
    c_expr.expr &:= "polIterChecks(";
    process_expr(params[1], c_expr);
    c_expr.expr &:= ", ";
    process_expr(params[2], c_expr);
    c_expr.expr &:= ");\n";
  end func;


const proc: process (POL_ITER_FINDINGS, in reference: function,
    in ref_list: params, inout expr_type: c_expr) is func

  begin
    setDiagnosticLine(c_expr);
    c_expr.expr &:= "polIterFindings(";
    process_expr(params[1], c_expr);
    c_expr.expr &:= ", ";
    process_expr(params[2], c_expr);
    c_expr.expr &:= ");\n";
  end func;


const proc: process (POL_NEXT_FILE, in reference: function,
    in ref_list: params, inout expr_type: c_expr) is func

  begin
    c_expr.expr &:= "polNextFile(";
    process_expr(params[1], c_expr);
    c_expr.expr &:= ", (genericType)(";
    process_expr(params[2], c_expr);
    c_expr.expr &:= "))";
  end func;


const proc: process (POL_POLL, in reference: function,
    in ref_list: params, inout expr_type: c_expr) is func

  begin
    setDiagnosticLine(c_expr);
    c_expr.expr &:= "polPoll(";
    process_expr(params[1], c_expr);
    c_expr.expr &:= ");\n";
  end func;


const proc: process (POL_REMOVE_CHECK, in reference: function,
    in ref_list: params, inout expr_type: c_expr) is func

  begin
    setDiagnosticLine(c_expr);
    c_expr.expr &:= "polRemoveCheck(";
    process_expr(params[1], c_expr);
    c_expr.expr &:= ", ";
    process_expr(params[2], c_expr);
    c_expr.expr &:= ", ";
    process_expr(params[3], c_expr);
    c_expr.expr &:= ");\n";
  end func;


const proc: process (POL_VALUE, in reference: function,
    in ref_list: params, inout expr_type: c_expr) is func

  begin
    c_expr.expr &:= "polValue(";
    process_expr(params[1], c_expr);
    c_expr.expr &:= ")";
  end func;