#!/usr/bin/gawk -f
# 
# Rewrite the interpreter source in $1 to use GNU C extensions, writing the
# modified file to stdout.
# 
# Author: Ian.Piumarta@INRIA.Fr
#
# Last edited: 2005-03-31 12:37:58 by piumarta on margaux.hpl.hp.com

#   Copyright (C) 1996-2004 by Ian Piumarta and other authors/contributors
#                              listed elsewhere in this file.
#   All rights reserved.
#   
#   This file is part of Unix Squeak.
# 
#      You are NOT ALLOWED to distribute modified versions of this file
#      under its original name.  If you modify this file then you MUST
#      rename it before making your modifications available publicly.
# 
#   This file 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.
#   
#   You may use and/or distribute this file ONLY as part of Squeak, under
#   the terms of the Squeak License as described in `LICENSE' in the base of
#   this distribution, subject to the following additional restrictions:
# 
#   1. The origin of this software must not be misrepresented; you must not
#      claim that you wrote the original software.  If you use this software
#      in a product, an acknowledgment to the original author(s) (and any
#      other contributors mentioned herein) in the product documentation
#      would be appreciated but is not required.
# 
#   2. You must not distribute (or make publicly available by any
#      means) a modified copy of this file unless you first rename it.
# 
#   3. This notice must not be removed or altered in any source distribution.
# 
#   Using (or modifying this file for use) in any context other than Squeak
#   changes these copyright conditions.  Read the file `COPYING' in the
#   directory `platforms/unix/doc' before proceeding with any such use.

BEGIN {
  print "/* This file has been post-processed for GNU C */\n\n";
# print "copying first section of file" > "/dev/stderr";
  stage= 0;
}

/#include "sq.h"/ {
  print "#include \"sqGnu.h\"\n";
  next;
}

# An inlining comment means the interpreter was not inlined

/inline\: true/ {
# print NR, $0 > "/dev/stderr";
# print "" > "/dev/stderr";
# print "*** interpreter was not inlined: bailing out! ***" > "/dev/stderr";
# print "" > "/dev/stderr";
  stage= -1;
}


(stage == 0) && /^int interpret\(void\) \{/ {
# print "interpret: adding static register assignments" > "/dev/stderr";
  stage= 1;
  print;
  next;
}

(stage == 0) && /^sqInt interpret\(void\) \{/ {
# print "interpret: adding static register assignments" > "/dev/stderr";
  stage= 1;
  print;
  next;
}

(stage == 1) && /^    char\* localIP;/ {
  print "    register char* localIP IP_REG;";
  next;
}

(stage == 1) && /^register struct foo \* foo = &fum;/ {
  print "    register struct foo * foo GP_REG= &fum;";
  next;
}

(stage == 1) && /^    char\* localSP;/ {
  print "    register char* localSP SP_REG;";
  next;
}

(stage == 1) && /^    int currentBytecode;/ {
  print "    register int currentBytecode CB_REG;";
  next;
}

(stage == 1) && /^    sqInt currentBytecode;/ {
  print "    register int currentBytecode CB_REG;";
  next;
}

(stage == 1) && /^$/ {
# print "interpret: adding bytecode dispatch table" > "/dev/stderr";
  print "    JUMP_TABLE;\n";
# print "interpret: rewriting case labels and outer breaks" > "/dev/stderr";
  stage= 2;
  FS=" ";
# FS="[ 	:]+";
  next;
}

(stage == 2) && /^		case / {
  print "		CASE(" (($NF) + 0) ")";
# print "		CASE(" $3 ")";
  next;
}

(stage == 2) && /^			break;/ {
  print "			BREAK;";
  next;
}

(stage == 2) && /^\}/ {
  stage= -1;
  print;
  next;
}

(stage == 3) && /^int primitiveResponse\(/ {
  print;
# print "primitiveResponse: adding primitive dispatch table" > "/dev/stderr";
  print "    PRIM_TABLE;\n";
# print "primitiveResponse: rewriting case labels" > "/dev/stderr";
  stage= 4;
  FS=" ";
# FS="[ 	:]+";
  next;
}

(stage == 3) && /^sqInt primitiveResponse\(/ {
  print;
# print "primitiveResponse: adding primitive dispatch table" > "/dev/stderr";
  print "    PRIM_TABLE;\n";
# print "primitiveResponse: rewriting case labels" > "/dev/stderr";
  stage= 4;
  FS=" ";
# FS="[ 	:]+";
  next;
}


(stage == 4) && /^	switch \(primitiveIndex\) \{/ {
# print "primitiveResponse: adding primitive dispatch" > "/dev/stderr";
  print "	PRIM_DISPATCH;";
  print;
  next;
}

(stage == 4) && /^	switch \(foo->primitiveIndex\) \{/ {
# print "primitiveResponse: adding primitive dispatch" > "/dev/stderr";
  print "	PRIM_DISPATCH;";
  print;
  next;
}

(stage == 4) && /^	case / {
  print "	CASE(" (($NF) + 0) ")";
# print "	CASE(" $3 ")";
  next;
}

(stage == 4) && /^\}/ {
# print "copying last section of file" > "/dev/stderr";
  stage= -1;
  FS=" ";
  print;
  next;
}

# default
{
  print;
  next;
}

END {
  if (stage != -1) {
    print "#error GNUIFICATION FAILED (", stage, ")"
  }
}
