source: git/modules/modgen/proc.cc @ 73d7b5

spielwiese
Last change on this file since 73d7b5 was 73d7b5, checked in by Kai Krüger <krueger@…>, 24 years ago
*** empty log message *** git-svn-id: file:///usr/local/Singular/svn/trunk@4321 2c84dea3-7e68-4137-9b89-c4e89433aadc
  • Property mode set to 100644
File size: 18.8 KB
Line 
1/*
2 * $Id: proc.cc,v 1.14 2000-05-12 12:24:44 krueger Exp $
3 */
4
5#include <stdio.h>
6#include <string.h>
7#include <stdlib.h>
8#include <ctype.h>
9#include "modgen.h"
10#include <mod2.h>
11#include <tok.h>
12#include "typmap.h"
13
14
15#if 1
16#  define logx printf
17#else
18#  define logx
19#endif
20/*#define DEBUG 1*/
21
22extern void PrintProc(procdefv pi);
23//void write_function(moddefv module, procdefv proc);
24static void write_function_declaration(procdefv pi, FILE *fp);
25static void  write_procedure_header(moddefv module, procdefv pi, FILE *fmtfp);
26static void gen_func_param_check(FILE *fp, procdefv pi, int i);
27
28
29#define SELF_CMD MAX_TOK+1
30
31/*========================================================================*/
32void setup_proc(
33  moddefv module,
34  procdefv proc
35)
36{
37  /* if proc is NULL, just return */
38  if( proc == NULL ) return;
39
40  if(trace) printf("\n\tcreating '%s'...", proc->procname); fflush(stdout);
41  fprintf(module->modfp, "#line %d \"%s\"\n", proc->lineno, module->filename);
42  modlineno+=1;
43
44  switch(proc->language) {
45      case LANG_C:
46        //  if(proc->funcname == NULL) proc->funcname = strdup(proc->procname);
47        if(proc->return_val.typ == NONE) {
48          if(proc->return_val.typname == NULL) {
49            proc->return_val.typname = strdup("NONE");
50          }
51        }
52 
53        /* write call to add procname to list */
54        fprintf(module->modfp, "  iiAddCproc(\"%s\",\"%s\",%s, mod_%s);\n",
55                module->name, proc->procname, 
56                proc->is_static ? "TRUE" : "FALSE",
57                proc->procname);
58        modlineno+=1;
59       
60        fprintf(module->modfp, "\n");
61        modlineno+=1;
62
63        write_procedure_header(module, proc, module->fmtfp);
64        fprintf(module->modfp_h,
65                "BOOLEAN mod_%s(leftv res, leftv h);\n", proc->procname);
66        break;
67       
68      case LANG_SINGULAR:
69        fprintf(module->modfp,"#if 0\n");
70        fprintf(module->modfp,
71                "  h = add_singular_proc(\"%s\", %d, %ld, %ld, %s);\n",
72                proc->procname, proc->lineno,
73                proc->sing_start, proc->sing_end,
74                proc->is_static ? "TRUE" : "FALSE");
75        modlineno+=1;
76        break;
77  }
78 
79  //  printf(" done\n");
80}
81
82/*========================================================================*/
83void write_function_header(
84  moddefv module,
85  procdefv proc
86  )
87{
88  if(!proc->flags.auto_header) return;
89  if(!proc->flags.start_of_code) return;
90
91  if(debug>4) {
92    printf("write_function_header: auto=%d\n", proc->flags.auto_header);
93    printf("write_function_header: declaration: do=%d, done=%d\n",
94           proc->flags.do_declaration, 
95           proc->flags.declaration_done);
96    printf("write_function_header: typecheck: do=%d, done=%d\n",
97           proc->flags.do_typecheck, 
98           proc->flags.typecheck_done);
99  }
100 
101  if(proc->flags.do_declaration && !proc->flags.declaration_done)
102    write_function_declaration(module, proc, module->fmtfp);
103
104  if(proc->flags.do_typecheck && !proc->flags.typecheck_done)
105    write_function_typecheck(module, proc, module->fmtfp);
106}
107
108/*========================================================================*/
109/*
110 * write declaration of function to file pointed by 'fp', usualy the
111 * header file.
112 *
113 * BOOLEAN mod_<procname>(leftv res, leftv h);
114 */
115static void write_function_declaration(procdefv pi, FILE *fp)
116{
117  int i;
118 
119#if 0
120  switch( pi->return_val.typ) {
121      case SELF_CMD:
122        fprintf(fp, "BOOLEAN %s(res, ", pi->funcname);
123        break;
124
125      default:
126        fprintf(fp, "%s %s(", type_conv[pi->return_val.typ],
127                pi->funcname);
128  }
129  for (i=0;i<pi->paramcnt; i++) {
130    fprintf(fp, "%s %s%d", type_conv[pi->param[i].typ], i);
131    if(i<pi->paramcnt-1) fprintf(fp, ", ");
132  }
133  fprintf(fp, ");\n\n");
134#endif
135}
136
137/*========================================================================*/
138void write_function_declaration(
139  moddefv module,
140  procdefv pi,
141  void *arg
142  )
143{
144  int i;
145  if(debug>4) printf("write_function_declaration: do=%d, done=%d\n",
146                     pi->flags.do_declaration, pi->flags.declaration_done);
147  if(pi->flags.declaration_done) return;
148  if(!pi->flags.do_declaration) return;
149  if(pi->paramcnt>0) {
150    fprintf(module->fmtfp, "#line %d \"%s\"\n", yylineno, module->filename);
151    fprintf(module->fmtfp, "#line @d \"%s.cc\"\n", module->name);
152    fprintf(module->fmtfp, "  leftv __v = __h, __v_save;\n");
153    fprintf(module->fmtfp, "  int __tok = NONE, __index = 0;\n");
154    for (i=0;i<pi->paramcnt; i++) {
155      fprintf(module->fmtfp, 
156              "  sleftv __s%s; leftv __z%s = &__s%s;\n", pi->param[i].varname,
157              pi->param[i].varname, pi->param[i].varname);
158      fprintf(module->fmtfp, "  %s %s;\n", type_conv[pi->param[i].typ],
159              pi->param[i].varname);
160    }
161   
162    fprintf(module->fmtfp, "#line %d \"%s\"\n", yylineno, module->filename);
163    fprintf(module->fmtfp, "\n");
164  }
165  pi->flags.declaration_done = 1;
166}
167
168/*========================================================================*/
169void write_function_nodecl(
170  moddefv module,
171  procdefv pi,
172  void *arg
173  )
174{
175  pi->flags.do_declaration = 0;
176  pi->flags.do_typecheck = 0;
177  pi->flags.auto_header = 0;
178}
179
180/*========================================================================*/
181void write_function_error(
182  moddefv module,
183  procdefv pi,
184  void *arg
185  )
186{
187  int i;
188
189  fprintf(module->fmtfp, "#line %d \"%s\"\n", yylineno, module->filename);
190  fprintf(module->fmtfp, "#line @d \"%s.cc\"\n", module->name);
191  fprintf(module->fmtfp, "#line %d \"%s\"\n", yylineno, module->filename);
192  fprintf(module->fmtfp, "\n");
193}
194
195/*========================================================================*/
196void write_function_typecheck(
197  moddefv module,
198  procdefv pi,
199  void *arg
200  )
201{
202  if(debug>4) printf("write_function_typecheck: do=%d, done=%d\n",
203                     pi->flags.do_typecheck, pi->flags.typecheck_done);
204  if(pi->flags.typecheck_done) return;
205  if(!pi->flags.do_typecheck) return;
206
207  fprintf(module->fmtfp, "#line %d \"%s\"\n", yylineno, module->filename);
208  fprintf(module->fmtfp, "#line @d \"%s.cc\"\n", module->name);
209  write_procedure_typecheck(module, pi, module->fmtfp);
210  fprintf(module->fmtfp, "#line %d \"%s\"\n", yylineno, module->filename);
211  pi->flags.typecheck_done = 1;
212}
213
214/*========================================================================*/
215void write_function_result(
216  moddefv module,
217  procdefv pi,
218  void *arg
219  )
220{
221  fprintf(module->fmtfp, "  __res->data =%s\n", arg);
222  pi->flags.result_done = 1;
223  write_procedure_return(module, pi, module->fmtfp);
224}
225
226/*========================================================================*/
227void write_function_return(
228  moddefv module,
229  procdefv pi,
230  void *arg
231  )
232{
233  int i;
234
235  if(arg!=NULL) {
236    if( pi->funcname != NULL ) free(pi->funcname);
237    pi->funcname = strdup((char *)arg);
238    if(debug>2)printf("CMD: return(%s)\n", arg);
239
240    /* write function declaration to header file */
241    switch( pi->return_val.typ) {
242        case SELF_CMD:
243          fprintf(module->modfp_h, "BOOLEAN %s(__res, ", pi->funcname);
244          break;
245
246        default:
247          fprintf(module->modfp_h, "//%s %s(", type_conv[pi->return_val.typ],
248                  pi->funcname);
249    }
250    for (i=0;i<pi->paramcnt; i++) {
251      fprintf(module->modfp_h, "%s %s", type_conv[pi->param[i].typ], 
252              pi->param[i].varname);
253      if(i<pi->paramcnt-1) fprintf(module->modfp_h, ", ");
254    }
255    fprintf(module->modfp_h, ");\n\n");
256  }
257  else {
258    if(debug>2)printf("CMD: return()\n");
259  }
260 
261  fprintf(module->fmtfp, "#line %d \"%s\"\n", yylineno, module->filename);
262  write_procedure_return(module, pi, module->fmtfp);
263}
264
265void write_function_singularcmd(
266  moddefv module,
267  procdefv pi,
268  void *arg
269)
270{
271  int i;
272 
273  if(trace)printf("\n\t\tsingular command block...");
274  fprintf(module->fmtfp, "#line @d \"%s.cc\"\n", module->name);
275  fprintf(module->fmtfp, "/* code for running singular commands */\n");
276  fprintf(module->fmtfp, "/*\n");
277  fprintf(module->fmtfp, " * #line %d \"%s\"\n", yylineno, module->filename);
278  fprintf(module->fmtfp, " *\n");
279  fprintf(module->fmtfp, " * get idhdl for '%s'\n", arg);
280  fprintf(module->fmtfp, " * building leftv of arguments\n");
281  fprintf(module->fmtfp, " * sleftv cmdret = iiMake_proc(cmd, ???, sl)\n");
282  fprintf(module->fmtfp, " *\n");
283  fprintf(module->fmtfp, "### SINGULAR command: '%s'\n", arg);
284  fprintf(module->fmtfp, "*/\n");
285}
286
287/*========================================================================*/
288/*
289 * write declaration of function to file pointed by 'fp', usualy the
290 * <module>.cc file
291 *
292 * BOOLEAN mod_<procname>(leftv res, leftv h)
293 * {
294 *    block of automatic type-checking and conversation
295 *
296 *    c++Code if any in the definition-file
297 *   
298 */
299static void  write_procedure_header(
300  moddefv module,
301  procdefv pi,
302  FILE *fmtfp
303)
304{
305  int cnt = 0, i;
306 
307  if(trace)printf("\n\t\theader..."); fflush(stdout);
308 
309  fprintf(fmtfp, "#line %d \"%s\"\n", pi->lineno, module->filename);
310  fprintf(fmtfp, "BOOLEAN mod_%s(leftv __res, leftv __h)\n{\n", pi->procname);
311}
312
313/*========================================================================*/
314/*
315 * write declaration of function to file pointed by 'fp', usualy the
316 * <module>.cc file
317 *
318 * BOOLEAN mod_<procname>(leftv res, leftv h)
319 * {
320 *    block of automatic type-checking and conversation
321 *
322 *    c++Code if any in the definition-file
323 *   
324 */
325void  write_procedure_typecheck(
326  moddefv module,
327  procdefv pi,
328  FILE *fmtfp
329)
330{
331  int cnt = 0, i;
332 
333  if(!pi->flags.declaration_done) return;
334 
335  if(trace)printf("type check..."); fflush(stdout);
336 
337  if(pi->paramcnt>0) {
338    /* loop over all parameters, for type-checking and conversation */
339    for (i=0;i<pi->paramcnt; i++) gen_func_param_check(fmtfp, pi, i);
340
341    fprintf(fmtfp, 
342            "  if(__v!=NULL) { __tok = __v->Typ(); goto mod_%s_error; }\n",
343            pi->procname);
344
345    fprintf(fmtfp, "\n");
346  }
347}
348
349/*========================================================================*/
350void write_finish_functions(
351  moddefv module,
352  procdefv proc
353)
354{
355  fprintf(module->modfp, "  return 0;\n}\n\n");
356  fflush(module->modfp);
357  modlineno+=3;
358 
359  fprintf(module->modfp, "#line %d \"%s.cc\"\n", modlineno++, module->name);
360  fprintf(module->modfp, "/* Help section */\n");
361  fprintf(module->modfp, "void fill_help_package(idhdl pl) {\n");
362  fprintf(module->modfp, "  namespaceroot->push(IDPACKAGE(pl), IDID(pl));\n");
363  modlineno+=3;
364  mod_copy_tmp(module->modfp, module->fmtfp2);
365  fprintf(module->modfp, "#line %d \"%s.cc\"\n", modlineno++, module->name);
366  fprintf(module->modfp, "  namespaceroot->pop();\n");
367  fprintf(module->modfp, "}  /* End of Help section */\n\n");
368  modlineno+=3;
369
370  fprintf(module->modfp, "/* Example section */\n");
371  fprintf(module->modfp, "void fill_example_package(idhdl pl) {\n");
372  fprintf(module->modfp, "  namespaceroot->push(IDPACKAGE(pl), IDID(pl));\n");
373  modlineno+=3;
374  mod_copy_tmp(module->modfp, module->fmtfp3);
375  fprintf(module->modfp, "#line %d \"%s.cc\"\n", modlineno++, module->name);
376  fprintf(module->modfp, "  namespaceroot->pop();\n");
377  fprintf(module->modfp, "} /* End of Example section */\n\n");
378  modlineno+=2;
379
380  mod_copy_tmp(module->modfp, module->fmtfp);
381  fprintf(module->modfp, "#line %d \"%s.cc\"\n", modlineno++, module->name);
382  if(trace)printf("  done.\n");fflush(stdout);
383  fclose(module->fmtfp); module->fmtfp = NULL;
384  fclose(module->fmtfp2); module->fmtfp2 = NULL;
385  fclose(module->fmtfp3); module->fmtfp3 = NULL;
386  return;
387}
388
389/*========================================================================*/
390/* automatic type-checking and conversation for one parameter */
391static void gen_func_param_check(
392  FILE *fp,
393  procdefv pi,
394  int i
395  )
396{
397  fprintf(fp, "  if(__v==NULL) goto mod_%s_error;\n", pi->procname);
398  fprintf(fp, "  __tok = __v->Typ();\n");
399  fprintf(fp, "  if((__index=iiTestConvert(__tok, %s))==0)\n",
400          pi->param[i].typname);
401  fprintf(fp, "     goto mod_%s_error;\n", pi->procname);
402  fprintf(fp, "  __v_save = __v->next;\n");
403  fprintf(fp, "  __v->next = NULL;\n");
404  fprintf(fp, "  if(iiConvert(__tok, %s, __index, __v, __z%s))\n",
405          pi->param[i].typname, pi->param[i].varname);
406  fprintf(fp, "     goto mod_%s_error;\n", pi->procname);
407  fprintf(fp, "  __v = __v_save;\n");
408  fprintf(fp, "  %s = (%s)__z%s->Data();\n", pi->param[i].varname,
409          type_conv[pi->param[i].typ], pi->param[i].varname);
410 
411}
412
413/*========================================================================*/
414/*
415 * write end of function to file pointed by 'fp', usualy the
416 * <module>.cc file
417 *
418 * ...
419 *
420 *
421 */
422void write_procedure_return(
423  moddefv module,
424  procdefv pi,
425  FILE *fmtfp
426)
427{
428  int i;
429 
430  if(trace)printf("\n\t\treturn block...");
431   
432  if(debug>2)printf("### RETURN: '%s' '%s' '%d'\n", pi->return_val.name,
433         pi->return_val.typname, pi->return_val.typ);
434  fprintf(module->fmtfp, "#line @d \"%s.cc\"\n", module->name);
435  if(pi->funcname == NULL) {
436    if(!pi->flags.result_done) fprintf(fmtfp, "  __res->data = NULL;\n");
437    fprintf(fmtfp, "  __res->rtyp = %s;\n", pi->return_val.typname);
438    //fprintf(fmtfp, "  res->rtyp = NONE;\n");
439    //fprintf(fmtfp, "  res->data = NULL;\n");
440    fprintf(fmtfp, "  return FALSE;\n");
441  }
442  else
443    switch( pi->return_val.typ) {
444        case SELF_CMD:
445          fprintf(fmtfp, "    return(%s(__res", pi->funcname);
446          for (i=0;i<pi->paramcnt; i++)
447            fprintf(fmtfp, ", (%s) __%s->Data()",
448                    type_conv[pi->param[i].typ], pi->param[i].varname);
449          fprintf(fmtfp, "));\n\n");
450          break;
451
452        case NONE:
453          if(!pi->flags.result_done) fprintf(fmtfp, "  __res->data = NULL;\n");
454          fprintf(fmtfp, "  __res->rtyp = %s;\n", pi->return_val.typname);
455          fprintf(fmtfp, "  return(%s(", pi->funcname);
456          for (i=0;i<pi->paramcnt; i++) {
457            fprintf(fmtfp, "(%s) __%s->Data()",
458                    type_conv[pi->param[i].typ], pi->param[i].varname);
459            if(i<pi->paramcnt-1) fprintf(fmtfp, ", ");
460          }
461          fprintf(fmtfp, "));\n\n");
462          break;
463         
464        default:
465          fprintf(fmtfp, "  __res->rtyp = %s;\n", pi->return_val.typname);
466          fprintf(fmtfp, "  __res->data = (void *)%s(", pi->funcname);
467          for (i=0;i<pi->paramcnt; i++) {
468            fprintf(fmtfp, "%s", pi->param[i].varname);
469//            fprintf(fmtfp, "(%s) %s->Data()",
470//                    type_conv[pi->param[i].typ], pi->param[i].varname);
471            if(i<pi->paramcnt-1) fprintf(fmtfp, ", ");
472          }
473          fprintf(fmtfp, ");\n");
474          fprintf(fmtfp, "  if(__res->data != NULL) return FALSE;\n");
475          fprintf(fmtfp, "  else return TRUE;\n\n");
476    }
477}
478
479/*========================================================================*/
480
481/*========================================================================*/
482/*
483    if(pi->param[0].typ==SELF_CMD) {
484      if(pi->c_code != NULL) fprintf(fp, "%s\n", pi->c_code);
485 
486      fprintf(fp, "  return(%s(res,h));\n", pi->funcname);
487      fprintf(fp, "}\n\n");
488    }
489    else {
490*/
491
492void write_function_errorhandling(
493  moddefv module,
494  procdefv pi
495  )
496{
497  int cnt = 0, i;
498 
499  switch(pi->language) {
500      case LANG_C:
501        if(pi->paramcnt>0) {
502          if(pi->flags.typecheck_done) {
503            if(trace)printf("\n\t\terror handling..."); fflush(stdout);
504            fprintf(module->fmtfp, "  mod_%s_error:\n", pi->procname);
505            fprintf(module->fmtfp, "    Werror(\"%s(`%%s`) is not supported\", Tok2Cmdname(__tok));\n",
506                    pi->procname);
507            fprintf(module->fmtfp, "    Werror(\"expected %s(", pi->procname);
508            for (i=0;i<pi->paramcnt; i++) {
509              fprintf(module->fmtfp, "'%s'", pi->param[i].name);
510              if(i!=pi->paramcnt-1) fprintf(module->fmtfp, ",");
511            }
512            fprintf(module->fmtfp, ")\");\n");
513            fprintf(module->fmtfp, "    return TRUE;\n");
514          } 
515        }
516        fprintf(module->fmtfp, "}\n\n");
517        break;
518      case LANG_SINGULAR:
519        fprintf(module->binfp, "}\n// end of procedure %s\n\n", pi->procname);
520        fprintf(module->modfp, "  if( h != NULL) {\n");
521        fprintf(module->modfp, "    IDPROC(h)->data.s.body_end = %ld;\n",
522                ftell(module->binfp));
523        fprintf(module->modfp, "    IDPROC(h)->data.s.proc_end = %ld;\n",
524                ftell(module->binfp));
525        fprintf(module->modfp, "  }\n");
526        break;
527  }
528}
529
530/*========================================================================*/
531void write_help(
532  moddefv module,
533  procdefv pi
534  )
535{
536  if(pi->help_string!=NULL) {
537    fprintf(module->fmtfp2, "#line %d \"%s\"\n", pi->lineno_other,
538            module->filename);
539    fprintf(module->fmtfp2, "  enter_id(\"%s\",", pi->procname);
540    fprintf(module->fmtfp2, " \"%s\", STRING_CMD);\n\n", pi->help_string);
541  }
542}
543
544/*========================================================================*/
545void write_example(
546  moddefv module,
547  procdefv pi
548  )
549{
550  /* if proc is NULL, just return */
551  if( pi == NULL ) return;
552
553  if(pi->example_string!=NULL) {
554    fprintf(module->fmtfp3, "#line %d \"%s\"\n", pi->lineno_other,
555            module->filename);
556    fprintf(module->fmtfp3, "  enter_id(\"%s\",\n", pi->procname);
557    fprintf(module->fmtfp3, " \"%s\", STRING_CMD);\n\n", pi->example_string);
558  }
559}
560
561/*========================================================================*/
562int write_singular_procedures(
563  moddefv module,
564  procdefv proc
565  )
566{
567  if(module->binfp==NULL) {
568    char filename[512];
569
570    //filename = (char *)malloc(strlen(module->name)+5+4);
571    //sprintf(filename, "tmp/%s.bin", module->name);
572    strcpy(filename, build_filename(module, module->name, 3));
573
574    if( (module->binfp = fopen(filename, "w")) == NULL) {
575      //free(filename);
576      return -1;
577    }
578    if(trace)printf("Creating %s, ", filename);fflush(stdout);
579
580    //free(filename);
581  }
582 
583  /* */
584  fprintf(module->binfp, "// line %d \"%s\"\n", proc->lineno,
585          module->filename);
586  fprintf(module->binfp, "// proc %s\n", proc->procname);
587  proc->sing_start = ftell(module->binfp);
588 
589  return 0;
590}
591
592/*========================================================================*/
593void write_singular_parameter(
594  moddefv module,
595  int lineno,
596  char *typname,
597  char *varname
598  )
599{
600  fprintf(module->binfp, "  parameter %s %s;\n", typname, varname);
601}
602
603/*========================================================================*/
604void write_codeline(
605  moddefv module,
606  procdefv proc,
607  char *line,
608  int lineno
609  )
610{
611  switch(proc->language) {
612      case LANG_SINGULAR:
613        if(lineno>=0)
614          fprintf(module->binfp, "// #line %d \"%s\"\n",
615                                          lineno, module->filename);
616        fprintf(module->binfp, "%s", line); break;
617
618      case LANG_C: 
619        write_function_header(module, proc);
620        if(lineno>=0) {
621          fprintf(module->fmtfp, "#line %d \"%s\"\n",
622                  lineno, module->filename);
623          fprintf(module->fmtfp, "#line @d \"%s.cc\"\n", module->name);
624        }
625        fprintf(module->fmtfp, "%s", line); break;
626  }
627}
628
629/*========================================================================*/
Note: See TracBrowser for help on using the repository browser.