
#CMD meth Vec "access" len "return length of the Vec" TYPE Num NAME _len PARAMS 
#CMD meth Vec "access" at: "get element at index a, modulo length of Vec" TYPE Pro NAME at_ PARAMS {Num a}
#CMD meth Vec "access" at:put:  "put element b at given a, modulo length of Vec" TYPE void NAME at_put_ PARAMS {Num a} { Pro b}
#CMD meth Vec "access" append:,ap: "add new element ato end of Vec" TYPE void NAME append_ PARAMS {Pro a}


#new JavaMeth(terp.tObj, "equals:", "") {
#  public Obj apply(Frame f, Pro r, Pro[] args) {
#    assert args.length == 1;
#    return r.equals(args[0]) ? terp.instTrue : terp.instFalse;
#  }
#};


proc wrap {file} {
  set f [open $file]
  while {[gets $f line] >= 0} {
    if [regexp {^// =(.*)} [string trim $line] - cmd] {
      while {[gets $f line2] >= 0} {
        if [regexp {^//(.*)} [string trim $line2] - cmd2] {
          append cmd " $cmd2"
        } else {
          break
        }
      }

      set verb [lindex $cmd 0]
      set cls [lindex $cmd 1]
      set group [lindex $cmd 2]
      set kws [lindex $cmd 3]
      set remark [lindex $cmd 4]
      set kw [split $kws ","]
      set kw0 [lindex $kw 0]
      set kw1 [lindex $kw 1]

      if {$verb == "meth"} {

        gets $f line3
        gets $f line4
        set decl "$line2 $line3 $line4"
        if [regexp {\s*public\s+(\w+)\s+(\w+)\s*[(]([^{}]*)[)]} $decl - type name params] {
           set pp [split $params ","]
           puts "// CMD $cmd TYPE $type NAME $name PARAMS $pp"
           puts "// CLS $cls GROUP \"$group\" METH $kws REMARK \"$remark\""
	   puts ""
	   puts "new JavaMeth(terp.t$cls, \"$kw0\", \"$kw1\") {"
	   puts "  public Pro apply(Frame f, Pro r, Pro\[\] args) {"
	   puts "    $cls self = ($cls) r;"
	   set i 0
	   set call "self.$name ("
	   set comma ""
	   foreach p $pp {
	     set atype [lindex $p 0]
	     set aname [lindex $p 1]
	     append call "$comma"
	     set c [format "%c" [expr 97+$i]]
	     puts "    $atype $c = ($atype) args\[$i\];"
	     append call "$c"
	     incr i
	     set comma ", "
	   }
	   if {$type == "void"} {
	     puts "    $call);"
	     puts "    return self;"
	   } else {
	     puts "    return $call);"
	   }
	   puts "  }"
	   puts "};"
	   puts "/////////////////////////////////////"



        } else {
          error "Dont understand method decl <$decl> after <$cmd>"
        }
      }
    }
  }
}

puts "
package terse.vm;

import java.util.Arrays;
import java.util.HashMap;
import java.util.ArrayList;
import java.util.regex.Pattern;

import terse.vm.Cls.JavaMeth;
import terse.vm.Cls.StrMeth;
import terse.vm.Expr.Seq;
import terse.vm.Expr.Send;
import terse.vm.Terp.Frame;

import terse.vm.Pro.Blk;
import terse.vm.Pro.Buf;
import terse.vm.Pro.Dict;
import terse.vm.Pro.Undefined;
import terse.vm.Pro.Num;
import terse.vm.Pro.Obj;
import terse.vm.Pro.Str;
import terse.vm.Pro.Sys;
import terse.vm.Pro.Vec;
import terse.vm.Usr.Tmp;

public class Wrap extends Static \{

  public static void install(final Terp terp) \{

"

wrap Pro.java

puts "
  \}
\}
"
