diff --git a/bin/precompile.pike b/bin/precompile.pike index 5f3649d48a6a0ea37edf3551bbe1fc4cc4725e65..1a9779c29168ed06a29a46f4e1e6c751bc52332e 100644 --- a/bin/precompile.pike +++ b/bin/precompile.pike @@ -35,11 +35,14 @@ * * BUGS/LIMITATIONS * o Parenthesis must match, even within #if 0 - * o Not all Pike types are supported yet - * o No support for class variables yet - * o No support for set_init/exit/gc_mark/gc_check_callback - * o Does not generate pike_module_init/exit automatically yet + * o Not all Pike types are supported yet. + * o No support for functions that takes variable number of arguments yet. + * o No support for class variables yet. + * o No support for set_init/exit/gc_mark/gc_check_callback. * o No support for 'char *', 'double' etc. + * o RETURN; (void) doesn't work yet + * o need a RETURN_NULL; or something.. RETURN 0; might work but may + * be confusing as RETURN x; will not work if x is zero. * */ @@ -274,8 +277,6 @@ array recursive(mixed func, array data, mixed ... args) { array ret=({}); - data=func(data, @args); - foreach(data, mixed foo) { if(arrayp(foo)) @@ -286,7 +287,7 @@ array recursive(mixed func, array data, mixed ... args) } } - return ret; + return func(ret, @args); } mapping parse_attributes(array attr) @@ -318,6 +319,7 @@ string file; array convert(array x) { array addfuncs=({}); + array exitfuncs=({}); array x=x/({"PIKECLASS"}); array ret=x[0]; @@ -334,16 +336,28 @@ array convert(array x) string name=proto[p]->text; mapping attributes=parse_attributes(proto[p+2..]); - [ array classcode, array classaddfuncs ]=convert(body[1..sizeof(body)-2]); + [ array classcode, array classaddfuncs, array classexitfuncs ]= + convert(body[1..sizeof(body)-2]); + ret+=({ sprintf("#define class_%s_defined\n",name), }); ret+=classcode; + addfuncs+=({ + sprintf("#ifdef class_%s_defined\n",name), " start_new_program();\n", })+ - addfuncs+ + classaddfuncs+ ({ sprintf(" end_class(%O,%d);\n",name, attributes->flags || "0"), + sprintf("#iendif\n"), + }); + + exitfuncs+=({ + sprintf("#ifdef class_%s_defined\n",name), + })+ + classexitfuncs+ + ({ + sprintf("#iendif\n"), }); - } x=ret/({"PIKEFUN"}); @@ -377,6 +391,7 @@ array convert(array x) // werror(" args=%O\n",args); ret+=({ + sprintf("#define f_%s_defined\n",name), sprintf("void f_%s(INT32 args) {\n",name), }); @@ -389,6 +404,7 @@ array convert(array x) addfuncs+=({ + sprintf("#ifdef f_%s_defined\n",name), PC.Token(sprintf(" %s(%O,f_%s,tFunc(%s,%s),%s);\n", attributes->efun ? "ADD_EFUN" : "ADD_FUNCTION", attributes->name || name, @@ -399,6 +415,7 @@ array convert(array x) (attributes->efun ? attributes->optflags : attributes->flags )|| "0" , ),proto[0]->line), + sprintf("#endif\n",name), }); int argnum; @@ -418,14 +435,14 @@ array convert(array x) { default: ret+=({ - PC.Token(sprintf("if(sp[%d].type != PIKE_T_%s)\n", + PC.Token(sprintf("if(sp[%d].type != PIKE_T_%s)", sp,upper_case(arg->basetype->text)),arg->line) }); break; case "program": ret+=({ - PC.Token(sprintf("if(!( %s=program_from_svalue(sp%+d)))\n", + PC.Token(sprintf("if(!( %s=program_from_svalue(sp%+d)))", arg->name,sp),arg->line) }); break; @@ -437,7 +454,7 @@ array convert(array x) { default: ret+=({ - PC.Token(sprintf(" SIMPLE_BAD_ARG_ERROR(%O,%d,%O);\n", + PC.Token(sprintf(" SIMPLE_BAD_ARG_ERROR(%O,%d,%O);\n", attributes->errname || attributes->name || name, argnum+1, arg->typename),arg->line), @@ -486,24 +503,13 @@ array convert(array x) } if(sizeof(body)) - { - ret+=({ - body, - }); - } - ret+=({ - "}\n" - }); + ret+=({body}); + ret+=({ "}\n" }); - if(sizeof(rest)) - { - ret+=recursive(replace,rest,PC.Token("INIT",0),addfuncs); - } - + ret+=rest; } - - return ({ ret, addfuncs }); + return ({ ret, addfuncs, exitfuncs }); } int main(int argc, array(string) argv) @@ -515,7 +521,23 @@ int main(int argc, array(string) argv) x=PC.tokenize(x,file); x=PC.group(x); - x=convert(x); + array tmp=convert(x); + x=tmp[0]; + x=recursive(replace,x,PC.Token("INIT",0),tmp[1]); + x=recursive(replace,x,PC.Token("EXIT",0),tmp[2]); - write(PC.reconstitute_with_line_numbers(x[0])); + if(equal(x,tmp[0])) + { + // No INIT / EXIT, add our own stuff.. + + x+=({ + "void pike_module_init(void) {\n", + tmp[1], + "}\n", + "void pike_module_exit(void) {\n", + tmp[2], + "}\n", + }); + } + write(PC.reconstitute_with_line_numbers(x)); }