diff --git a/bin/precompile.pike b/bin/precompile.pike index 3684e070f35881a62d9ad18d947c578c9ff8a5d4..761794a2ca6f999668ba3210d27be5a6b77c91c2 100644 --- a/bin/precompile.pike +++ b/bin/precompile.pike @@ -6,17 +6,22 @@ * * The input can look something like this: * - * PIKEFUNC int function_name (int x) - * attribute; - * attribute value; + * PIKECLASS fnord + * attributes; * { - * C code using 'x'. * - * RETURN x; + * PIKEFUNC int function_name (int x) + * attribute; + * attribute value; + * { + * C code using 'x'. + * + * RETURN x; + * } * } * - * All the ADD_EFUN/ADD_FUNCTION calls will be inserted instead of the - * word INIT in your code. + * All the begin_class/ADD_EFUN/ADD_FUNCTION calls will be inserted + * instead of the word INIT in your code. * * Currently, the following attributes are understood: * efun; makes this function a global constant (no value) @@ -29,7 +34,7 @@ * BUGS/LIMITATIONS * o Parenthesis must match, even within #if 0 * o Not all Pike types are supported yet - * o Line numbers are wrong after INIT + * o No support for class variables yet */ #define PC Parser.C @@ -151,6 +156,7 @@ mapping(string:string) parse_arg(array x) if(sizeof(ret->type/({"|"}))>1) ret->basetype="mixed"; ret->ctype=cname(ret->basetype); + ret->typename=merge(recursive(strip_type_assignments,ret->type)); return ret; } @@ -201,6 +207,7 @@ string convert_type(array s) } } + string make_pop(mixed howmany) { switch(howmany) @@ -241,7 +248,7 @@ array strip_type_assignments(array data) int pos; while( (pos=search(data,PC.Token("=",0))) != -1) - data=data[pos-2]+data[pos+1]; + data=data[..pos-2]+data[pos+1..]; return data; } @@ -352,7 +359,6 @@ array convert(array x) // werror(" args=%O\n",args); ret+=({ - sprintf("\n#line %d %O\n",rettype[0]->line,file), sprintf("void f_%s(INT32 args) {\n",name), }); @@ -360,13 +366,11 @@ array convert(array x) foreach(args, mapping arg) ret+=({ -// sprintf("\n#line %d %O\n",rettype[0]->line,file), sprintf("%s %s;\n",arg->ctype, arg->name) }); addfuncs+=({ - sprintf("\n#line %d %O\n",rettype[0]->line,file), sprintf(" %s(%O,f_%s,tFunc(%s,%s),%s);\n", attributes->efun ? "ADD_EFUN" : "ADD_FUNCTION", name, @@ -383,7 +387,6 @@ array convert(array x) argnum=0; ret+=({ -// sprintf("\n#line %d %O\n",rettype[0]->line,file), sprintf("if(args != %d) wrong_number_of_args_error(%O,args,%d);\n", sizeof(args), name, @@ -393,7 +396,6 @@ array convert(array x) int sp=-sizeof(args); foreach(args, mapping arg) { -// ret+=({ sprintf("\n#line %d %O\n",rettype[0]->line,file), }); if(arg->basetype != "mixed") { ret+=({ @@ -402,7 +404,7 @@ array convert(array x) sprintf(" SIMPLE_BAD_ARG_ERROR(%O,%d,%O);\n", name, argnum+1, - merge(arg->type)), + arg->typename), }); } @@ -448,7 +450,6 @@ array convert(array x) if(sizeof(body)) { ret+=({ - sprintf("#line %d %O\n",body[0]->line,file), body, }); } @@ -458,10 +459,7 @@ array convert(array x) if(sizeof(rest)) { - ret+=({ - sprintf("#line %d %O\n",rest[0]->line,file), - })+ - recursive(replace,rest,PC.Token("INIT",0),addfuncs); + ret+=recursive(replace,rest,PC.Token("INIT",0),addfuncs); } } @@ -476,10 +474,10 @@ int main(int argc, array(string) argv) file=argv[1]; x=Stdio.read_file(file); x=PC.split(x); - x=PC.tokenize(x); + x=PC.tokenize(x,file); x=PC.group(x); x=convert(x); - write(merge(x[0])); + write(PC.reconstitute_with_line_numbers(x[0])); } diff --git a/lib/modules/Parser.pmod/C.pmod b/lib/modules/Parser.pmod/C.pmod index 90e6c54c8ad9cbaacb21a05026e0979d7bebc9fc..b31026e29c1fa044d3c757a80ec540b7ce3402de 100644 --- a/lib/modules/Parser.pmod/C.pmod +++ b/lib/modules/Parser.pmod/C.pmod @@ -189,12 +189,13 @@ class Token { int line; string text; - /* string file; */ + string file; - void create(string t, int l) + void create(string t, int l, void|string f) { text=t; line=l; + file=f; } string _sprintf(int how) @@ -204,7 +205,7 @@ class Token case 's': return text; case 'O': - return sprintf("Token(%O,%d)",text,line); + return sprintf("Token(%O,%O,%d)",text,file,line); } } @@ -222,15 +223,20 @@ class Token { return predef::`+(@s,text); } + + mixed _cast(string to) + { + if(to=="string") return text; + } } -array(Token) tokenize(array(string) s) +array(Token) tokenize(array(string) s, void|string file) { array(Token) ret=allocate(sizeof(s)); int line=1; for(int e=0;e<sizeof(s);e++) { - ret[e]=Token(s[e],line); + ret[e]=Token(s[e],line,file); line+=sizeof(s[e]/"\n")-1; } return ret; @@ -276,3 +282,29 @@ string simple_reconstitute(array(Token) tokens) { return FLATTEN(tokens->text) * ""; } + +string reconstitute_with_line_numbers(array(string|object(Token)|array) tokens) +{ + int line=1; + string file; + string ret=""; + foreach(FLATTEN(tokens), mixed tok) + { + if(objectp(tok)) + { + if((tok->line && tok->line != line) || + (tok->file && tok->file != file)) + { + if(strlen(ret) && ret[-1]!='\n') ret+="\n"; + ret+=sprintf("#line %d %O\n",tok->line,tok->file); + line=tok->line; + file=tok->file; + } + tok=tok->text; + } + ret+=tok; + line+=sizeof(tok/"\n")-1; + } + + return ret; +} diff --git a/src/builtin.cmod b/src/builtin.cmod index c1d8d80aa89180e909325ac97d96a676a4a385fc..cede3d048a24f42e2b2ca49a20f017da9d904a2e 100644 --- a/src/builtin.cmod +++ b/src/builtin.cmod @@ -101,5 +101,5 @@ PIKEFUN mapping(1:2) mkmapping(array(1=mixed) a, array(2=mixed) b) void init_builtin(void) { - INIT; +INIT }