pike.git / src / post_modules / GL / gen.pike

version» Context lines:

pike.git/src/post_modules/GL/gen.pike:1: + #!/usr/local/bin/pike + /* +  V=void +  I=int +  D=double +  F=float +  E=enum +  B=bitfield +  R=double/float +  Q=int/float +  Z=(byte/)double/float/int/short    -  +  +XXXX = 3/4/array(3/4) +  +XXX = 2/3/4/array(2/3/4) +  =XXXX = 4/array(4) +  =XXX = 3/array(3) +  @X = 1/array(n) +  +  # = like =, but add count +  ! = like =, but no vector version available +  + */ +  + inherit "features"; + inherit "constants"; +  + void error(string msg, mixed ... args) + { +  if(sizeof(args)) +  msg = sprintf(msg, @args); +  werror(msg+"\n"); +  exit(1); + } +  + array(string|array(string)) special_234(int mi, int mx, string ty) + { +  string tm="BIT_FLOAT|BIT_INT", baset="float|int", rt="if"; +  array(string) typ=({}); +  int i, ad; +  if(sizeof(Array.uniq(values(ty)))!=1) +  error("Unparsable 234 type '%s'.", ty); +  switch(ty[0]) { +  case 'E': +  case 'B': +  case 'I': +  baset="int"; +  tm="BIT_INT"; +  rt="i"; +  break; +  case 'D': +  ad=1; /* fallthrough */ +  case 'F': +  baset="float"; +  tm="BIT_FLOAT"; +  rt=(ad?"":"f"); +  break; +  case 'R': +  rt="f"; +  case 'Z': +  ad=1; +  break; +  case 'Q': +  break; +  default: +  error("Unknown 234 type '%s'.", ty[0..0]); +  } +  if(ad) +  rt+="d"; +  for(i=0; i<mx; i++) { +  string t = baset; +  if(!i) +  t+="|array("+baset+")"; +  if(i>=mi || i>0) +  t+="|void"; +  typ+=({t}); +  } +  return ({typ,tm,rows((['i':"ZT_INT",'f':"ZT_FLOAT",'d':"ZT_DOUBLE"]), +  values(rt))*"|",rt}); + } +  + array(string) gen_func(string name, string ty) + { +  string res="", got="", prot, vdec, vret, fu=name; +  array novec, args=({}), argt=({}); +  int r234; +  string rtypes; +  +  switch(ty[0]) { +  case 'V': +  prot=":void"; +  break; +  case 'I': +  prot=":int"; +  vdec="INT32"; +  vret="push_int"; +  break; +  default: +  error("%s: Unknown return type '%c'.", name, ty[0]); +  } +  +  res += "static void f_"+name+"(INT32 args)\n{\n"+ +  (vdec?(" "+vdec+" res;\n"):""); +  +  for(int i=1; i<sizeof(ty); i++) +  switch(ty[i]) { +  case 'B': +  case 'E': +  case 'I': +  argt += ({"int"}); +  args += ({ "arg"+i }); +  res += " INT32 arg"+i+";\n"; +  got += " arg"+i+"=sp["+(i-1)+"-args].u.integer;\n"; +  break; +  case 'D': +  argt += ({"float"}); +  args += ({ "arg"+i }); +  res += " double arg"+i+";\n"; +  got += " arg"+i+"=sp["+(i-1)+"-args].u.float_number;\n"; +  break; +  case 'F': +  argt += ({"float"}); +  args += ({ "arg"+i }); +  res += " float arg"+i+";\n"; +  got += " arg"+i+"=sp["+(i-1)+"-args].u.float_number;\n"; +  break; +  case '+': +  if(ty[i+1..]=="FFFF") +  continue; +  int mi, mx; +  switch(sizeof(ty[i+1..])) { +  case 3: +  mi = 2; mx = 4; break; +  case 4: +  mi = 3; mx = 4; break; +  default: +  error("Can't understand + followed by %d chars.\n", sizeof(ty[i+1..])); +  } +  array plusfix = special_234(mi, mx, ty[i+1..]); +  res += " struct zvalue4 zv4;\n"; +  argt += plusfix[0]; +  res += "\n int r234=check_234_args(\""+name+"\", args-"+(i-1)+", "+ +  mi+", "+mx+", "+plusfix[1]+", "+plusfix[2]+", &zv4);\n"; +  r234=1; +  rtypes=plusfix[3]; +  i=sizeof(ty); +  novec=indices(allocate(mx+1))[mi..]; +  break; +  case '#': +  fu += sizeof(ty[i+1..]); +  /* fallthrough */ +  case '!': +  case '=': +  array eqfix = special_234(sizeof(ty[i+1..]), sizeof(ty[i+1..]), +  ty[i+1..]); +  res += " struct zvalue4 zv4;\n"; +  argt += eqfix[0]; +  res += "\n check_234_args(\""+name+"\", args-"+(i-1)+", "+ +  sizeof(ty[i+1..])+", "+sizeof(ty[i+1..])+", "+eqfix[1]+", "+ +  eqfix[2]+", &zv4);\n"; +  r234=2; +  rtypes=eqfix[3]; +  if(ty[i]=='!') +  novec=indices(ty[i+1..]); +  i=sizeof(ty); +  break; +  case '@': +  array atfix = special_234(1, 1, ty[i+1..]); +  res += " union zvalue16 zv16;\n"; +  argt += atfix[0]; +  res += "\n int r1n=check_1n_args(\""+name+"\", args-"+(i-1)+", "+ +  atfix[1]+", "+atfix[2]+", &zv16);\n"; +  r234=3; +  rtypes=atfix[3]; +  i=sizeof(ty); +  break; +  +  default: +  error("%s: Unknown parameter type '%c'.", name, ty[i]); +  } +  +  prot = (argt*",")+prot; +  +  if(sizeof(got)) +  res += "\n"+got+"\n"; +  +  switch(r234) +  { +  case 0: +  res += (vret?" res=":" ")+fu+"("+(args*",")+");\n"; +  break; +  case 1: +  if(sizeof(rtypes)==1) +  res += " switch(r234) {\n"+Array.map(novec, lambda(int i, string vret, +  string r, string fu, +  array(string) args) { +  return " case "+i+": "+ +  (vret?"res=":"")+ +  fu+i+"v("+ +  (args+({"zv4.v."+r}))* +  ","+"); break;"; +  }, vret, rtypes, fu, args)* +  "\n"+"\n }\n"; +  else +  res += " switch(zv4.ty) {\n"+ +  Array.map(indices(rtypes), +  lambda(int i, string r, string fu, string vret, +  array(string) args, array(int) novec) { +  return " case ZT_"+ +  (['i':"INT",'f':"FLOAT",'d':"DOUBLE"])[r[i]]+ +  ": switch(r234) {\n"+ +  Array.map(novec, lambda(int i, string vret, string r, +  string fu, array(string) args) { +  return " case "+i+": "+ +  (vret?"res=":"")+ +  fu+i+r+"v("+ +  (args+({"zv4.v."+r}))* +  ","+"); break;"; +  }, vret, r[i..i], fu, args)* +  "\n"+"\n }\n break;"; +  }, rtypes, fu, vret, args, novec)*"\n"+ +  "\n }\n"; +  break; +  case 2: +  if(sizeof(rtypes)==1) +  res += (vret?" res=":" ")+fu+"("+ +  ((args+(novec? Array.map(novec, lambda(int i, string rtypes) { +  return "zv4.v."+rtypes+"["+i+"]"; +  }, rtypes):({"zv4.v."+rtypes})))*",")+ +  ");\n"; +  else +  res += " switch(zv4.ty) {\n"+ +  Array.map(indices(rtypes), +  lambda(int i, string r, string fu, string vret, +  array(string) args, array(int) novec) { +  return " case ZT_"+ +  (['i':"INT",'f':"FLOAT",'d':"DOUBLE"])[r[i]]+": "+ +  (vret?"res=":"")+fu+r[i..i]+(novec?"(":"v(")+ +  ((args+(novec? Array.map(novec, lambda(int i, string r) { +  return "zv4.v."+r+ +  "["+i+"]"; +  }, r[i..i]): +  ({"zv4.v."+r[i..i]})))*",")+"); break;"; +  }, rtypes, fu, vret, args, novec)*"\n"+ +  "\n }\n"; +  break; +  case 3: +  if(sizeof(rtypes)==1) +  res += " if(r1n&ZT_ARRAY)\n"+ +  (vret?" res=":" ")+fu+"v("+(args+({"zv16."+rtypes}))*","+ +  ");\n else\n"+ +  (vret?" res=":" ")+fu+"("+(args+({"zv16."+rtypes+"[0]"}))*","+ +  ");\n"; +  else +  res += " switch(r1n) {\n"+ +  Array.map(indices(rtypes), +  lambda(int i, string r, string fu, string vret, +  array(string) args, array(int) novec) { +  return " case ZT_"+ +  (['i':"INT",'f':"FLOAT",'d':"DOUBLE"])[r[i]]+": "+ +  (vret?"res=":"")+fu+r[i..i]+"("+ +  ((args+({"zv16."+r[i..i]+"[0]"}))*",")+"); break;\n"+ +  " case ZT_ARRAY|ZT_"+ +  (['i':"INT",'f':"FLOAT",'d':"DOUBLE"])[r[i]]+": "+ +  (vret?"res=":"")+fu+r[i..i]+"v("+ +  ((args+({"zv16."+r[i..i]}))*",")+"); break;"; +  }, rtypes, fu, vret, args, novec)*"\n"+ +  "\n }\n"; +  break; +  } +  +  res += " pop_n_elems(args);\n"; +  res += (vret? " "+vret+"(res);\n":" push_int(0);\n"); +  res += "}\n\n"; +  return ({res,prot}); + } +  + string gen() + { +  string res = ""; +  array t = Array.transpose(func_misc); +  array fn=t[0]; +  mapping ty = mkmapping(@t); +  mapping prot = ([]); +  foreach(indices(func_cat), string cat) { +  fn += func_cat[cat]; +  ty |= mkmapping(func_cat[cat], +  rows(({cat}), allocate(sizeof(func_cat[cat])))); +  } +  sort(fn); +  foreach(fn, string f) { +  array(string) r = gen_func(f, ty[f]); +  res += r[0]; +  prot[f]=r[1]; +  } +  res += "void add_auto_funcs()\n{\n"; +  foreach(fn, string f) +  res += " add_function_constant(\""+f+"\", f_"+f+",\n\t\t\t\"function("+ +  prot[f]+")\", OPT_SIDE_EFFECT);\n"; +  foreach(sort(indices(constants)), string co) +  res += " add_integer_constant(\""+co+"\", "+constants[co]+", 0);\n"; +  res += "}\n"; +  return res; + } +  + void main(int argc, array(string) argv) + { +  array(string) f = Stdio.File("stdin")->read()/"@@"; +  write(({f[0],gen(),@f[1..]})*""); + }   Newline at end of file added.