#! /bin/sh
# This file is part of GNU epsilon, a functional language implementation

# Copyright (C) 2002, 2003 Luca Saiu

# GNU epsilon 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, or (at your
# option) any later version.

# GNU epsilon 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 epsilon; see the file COPYING.  If not, write to the
# Free Software Foundation, Inc., 59 Temple Place - Suite 330,
# Boston, MA 02111-1307, USA.


./make_instructions_h
./make_all_scheme_instructions
./make_stringified_scheme_instructions


echo "/* This file is automatically generated. Do not edit. */" > output_scheme.c
cat output_scheme_c.head >> output_scheme.c

cd c_instructions
for CATEGORY in *; do
  if test $CATEGORY != "CVS"; then
    echo >> ../output_scheme.c
    echo "/* Instructions of category $CATEGORY: */" >> ../output_scheme.c
    cd $CATEGORY
    for I in *; do
      if test $I != "CVS" && test $I != nln; then
	# Output the switch case:
	echo "case $I:{" >> ../../output_scheme.c
	echo "  fprintf(output_stream, \"     ($I %i \", instruction_pointer);" \
	    >> ../../output_scheme.c

	# The names and numbers of parameters depend on $CATEGORY:
	if test $CATEGORY = nullary; then
	    true # Do nothing

	elif test $CATEGORY = integer; then
	    echo "  fprintf(output_stream, INTEGER_T_FORMAT, executable->instructions[instruction_pointer].parameter_1);" >> ../../output_scheme.c

	elif test $CATEGORY = integer_integer; then
	    echo "  fprintf(output_stream, INTEGER_T_FORMAT \" \", executable->instructions[instruction_pointer].parameter_1);" >> ../../output_scheme.c
	    echo "  fprintf(output_stream, INTEGER_T_FORMAT, executable->instructions[instruction_pointer].parameter_2);" >> ../../output_scheme.c

	elif test $CATEGORY = integer_integer_integer; then
	    echo "  fprintf(output_stream, INTEGER_T_FORMAT \" \", executable->instructions[instruction_pointer].parameter_1);" >> ../../output_scheme.c
	    echo "  fprintf(output_stream, INTEGER_T_FORMAT \" \", executable->instructions[instruction_pointer].parameter_2);" >> ../../output_scheme.c
	    echo "  fprintf(output_stream, INTEGER_T_FORMAT, executable->instructions[instruction_pointer].parameter_3);" >> ../../output_scheme.c

	elif test $CATEGORY = float; then
	    echo "  fprintf(output_stream, FLOAT_T_FORMAT \" \", executable->instructions[instruction_pointer].float_parameter);" >> ../../output_scheme.c

	elif test $CATEGORY = string; then
	    echo "  fprintf(output_stream, \"\\\"%s\\\" \", executable->string_constants[(integer_t)(executable->instructions[instruction_pointer].parameter_1)]);" >> ../../output_scheme.c

	elif test $CATEGORY = string_string; then
	    echo "  fprintf(output_stream, \"\\\"%s\\\" \", executable->string_constants[(integer_t)(executable->instructions[instruction_pointer].parameter_1)]);" >> ../../output_scheme.c
	    echo "  fprintf(output_stream, \"\\\"%s\\\" \", executable->string_constants[(integer_t)(executable->instructions[instruction_pointer].parameter_2)]);" >> ../../output_scheme.c

	elif test $CATEGORY = register; then
	    echo "  fprintf(output_stream, INTEGER_T_FORMAT, executable->instructions[instruction_pointer].parameter_1);" >> ../../output_scheme.c

	elif test $CATEGORY = register_register; then
	    echo "  fprintf(output_stream, INTEGER_T_FORMAT \" \", executable->instructions[instruction_pointer].parameter_1);" >> ../../output_scheme.c
	    echo "  fprintf(output_stream, INTEGER_T_FORMAT, executable->instructions[instruction_pointer].parameter_2);" >> ../../output_scheme.c

	elif test $CATEGORY = register_register_integer; then
	    echo "  fprintf(output_stream, INTEGER_T_FORMAT \" \", executable->instructions[instruction_pointer].parameter_1);" >> ../../output_scheme.c
	    echo "  fprintf(output_stream, INTEGER_T_FORMAT \" \", executable->instructions[instruction_pointer].parameter_2);" >> ../../output_scheme.c
	    echo "  fprintf(output_stream, INTEGER_T_FORMAT, executable->instructions[instruction_pointer].parameter_3);" >> ../../output_scheme.c

	elif test $CATEGORY = register_integer; then
	    echo "  fprintf(output_stream, INTEGER_T_FORMAT \" \", executable->instructions[instruction_pointer].parameter_1);" >> ../../output_scheme.c
	    echo "  fprintf(output_stream, INTEGER_T_FORMAT, executable->instructions[instruction_pointer].parameter_2);" >> ../../output_scheme.c

	elif test $CATEGORY = register_integer_integer; then
	    echo "  fprintf(output_stream, INTEGER_T_FORMAT \" \", executable->instructions[instruction_pointer].parameter_1);" >> ../../output_scheme.c
	    echo "  fprintf(output_stream, INTEGER_T_FORMAT \" \", executable->instructions[instruction_pointer].parameter_2);" >> ../../output_scheme.c
	    echo "  fprintf(output_stream, INTEGER_T_FORMAT, executable->instructions[instruction_pointer].parameter_3);" >> ../../output_scheme.c

	elif test $CATEGORY = register_integer_register; then
	    echo "  fprintf(output_stream, INTEGER_T_FORMAT \" \", executable->instructions[instruction_pointer].parameter_1);" >> ../../output_scheme.c
	    echo "  fprintf(output_stream, INTEGER_T_FORMAT \" \", executable->instructions[instruction_pointer].parameter_2);" >> ../../output_scheme.c
	    echo "  fprintf(output_stream, INTEGER_T_FORMAT, executable->instructions[instruction_pointer].parameter_3);" >> ../../output_scheme.c

	elif test $CATEGORY = register_register_register; then
	    echo "  fprintf(output_stream, INTEGER_T_FORMAT \" \", executable->instructions[instruction_pointer].parameter_1);" >> ../../output_scheme.c
	    echo "  fprintf(output_stream, INTEGER_T_FORMAT \" \", executable->instructions[instruction_pointer].parameter_2);" >> ../../output_scheme.c
	    echo "  fprintf(output_stream, INTEGER_T_FORMAT, executable->instructions[instruction_pointer].parameter_3);" >> ../../output_scheme.c

	elif test $CATEGORY = label; then
	    echo "  fprintf(output_stream, \"%i\", executable->instructions[instruction_pointer].label_parameter);" >> ../../output_scheme.c

	elif test $CATEGORY = exception; then
	    echo "  fprintf(output_stream, INTEGER_T_FORMAT, (integer_t)(executable->instructions[instruction_pointer].parameter_1));" >> ../../output_scheme.c

	elif test $CATEGORY = exception_label; then
	    echo "  fprintf(output_stream, INTEGER_T_FORMAT \" \", (integer_t)(executable->instructions[instruction_pointer].parameter_1));" >> ../../output_scheme.c
            echo "  fprintf(output_stream, \"%i\", executable->instructions[instruction_pointer].label_parameter);" >> ../../output_scheme.c

	elif test $CATEGORY = global; then
	    echo "  fprintf(output_stream, INTEGER_T_FORMAT, (integer_t)(executable->instructions[instruction_pointer].parameter_1));" >> ../../output_scheme.c

	elif test $CATEGORY = integer_label; then
	    echo "  fprintf(output_stream, INTEGER_T_FORMAT \" \", (integer_t)(executable->instructions[instruction_pointer].parameter_1));" >> ../../output_scheme.c
            echo "  fprintf(output_stream, \"%i\", executable->instructions[instruction_pointer].label_parameter);" >> ../../output_scheme.c

	else
	  echo make_output_scheme_c: unknown category $CATEGORY > /dev/stderr
	  exit -1
	fi

	# Close case:
	echo "  fprintf(output_stream, \") ; instr. %i\\n\", instruction_pointer);" \
	    >> ../../output_scheme.c
	echo "  break;" >> ../../output_scheme.c
	echo "}" >> ../../output_scheme.c
      fi
    done # For each instruction $I in $CATEGORY
    cd ..
  fi
done # For each $CATEGORY
cd ..

cat output_scheme_c.tail >> output_scheme.c
