C:/Users/Dennis/src/lang/Life_start/Life/life-1.02/source/bi_sys.c

Go to the documentation of this file.
00001 /* Copyright 1992 Digital Equipment Corporation
00002    All Rights Reserved
00003 */
00004 /*      $Id: bi_sys.c,v 1.2 1994/12/08 23:08:17 duchier Exp $    */
00005 
00006 #ifndef lint
00007 static char vcid[] = "$Id: bi_sys.c,v 1.2 1994/12/08 23:08:17 duchier Exp $";
00008 #endif /* lint */
00009 
00010 #include "extern.h"
00011 #include "trees.h"
00012 #include "login.h"
00013 #include "parser.h"
00014 #include "copy.h"
00015 #include "token.h"
00016 #include "print.h"
00017 #include "lefun.h"
00018 #include "memory.h"
00019 #include "modules.h"
00020 #ifndef OS2_PORT
00021 #include "built_ins.h"
00022 #else
00023 #include "error.h"
00024 ptr_psi_term makePsiTerm(ptr_definition x);
00025 #endif
00026 
00027 #define copyPsiTerm(a,b)        (ptr_psi_term )memcpy(a,b,sizeof(psi_term))
00028 
00029 /******** C_TRACE
00030   With no arguments: Toggle the trace flag & print a message saying whether
00031   tracing is on or off.
00032   With argument 1: If it is top, return the trace flag and disable tracing.
00033   If it is true or false, set the trace flag to that value.  Otherwise, give
00034   an error.
00035   With argument 2: If it is top, return the stepflag and disable stepping.
00036   If it is true or false, set the stepflag to that value.  Otherwise, give
00037   an error.
00038 */
00039 long c_trace()
00040 {
00041   long success=TRUE;
00042   ptr_psi_term t,arg1,arg2;
00043 
00044   t=aim->a;
00045   deref_args(t,set_empty);
00046   get_two_args(t->attr_list,&arg1,&arg2);
00047   if (arg1) {
00048     deref_ptr(arg1);
00049     if (is_top(arg1)) {
00050       unify_bool_result(arg1,trace);
00051       trace=FALSE;
00052     }
00053     else if (arg1->type==true)
00054       trace=TRUE;
00055     else if (arg1->type==false)
00056       trace=FALSE;
00057     else {
00058       Errorline("bad first argument in %P.\n",t);
00059       /* report_error(t,"bad first argument"); */
00060       success=FALSE;
00061     }
00062   }
00063   if (arg2) {
00064     deref_ptr(arg2);
00065     if (is_top(arg2)) {
00066       unify_bool_result(arg2,stepflag);
00067       stepflag=FALSE;
00068     }
00069     else if (arg2->type==true)
00070       stepflag=TRUE;
00071     else if (arg2->type==false)
00072       stepflag=FALSE;
00073     else {
00074       Errorline("bad second argument in %P.\n",t);
00075       /* report_error(t,"bad second argument"); */
00076       success=FALSE;
00077     }
00078   }
00079   if (!arg1 && !arg2)
00080     toggle_trace();
00081   return success;
00082 }
00083 
00084 long c_tprove()
00085 {
00086   ptr_psi_term t;
00087 
00088   t=aim->a;
00089   deref_args(t,set_empty);
00090   set_trace_to_prove();
00091   return TRUE;
00092 }
00093 
00094 /******** C_STEP
00095   Toggle the single step flag & print a message saying whether
00096   single stepping mode is on or off.
00097 */
00098 static long c_step()
00099 {
00100   ptr_psi_term t;
00101 
00102   t=aim->a;
00103   deref_args(t,set_empty);
00104   toggle_step();
00105   return TRUE;
00106 }
00107 
00108 /******** C_VERBOSE
00109   Toggle the verbose flag & print a message saying whether
00110   verbose mode is on or off.
00111 */
00112 static long c_verbose()
00113 {
00114   ptr_psi_term t;
00115 
00116   t=aim->a;
00117   deref_args(t,set_empty);
00118   verbose = !verbose;
00119   printf("*** Verbose mode is turned ");
00120   printf(verbose?"on.\n":"off.\n");
00121   return TRUE;
00122 }
00123 
00124 /******** C_WARNING
00125   Toggle the warning flag & print a message saying whether
00126   warnings are printed or not.
00127   Default: print warnings.
00128   (Errors cannot be turned off.)
00129 */
00130 static long c_warning()
00131 {
00132   ptr_psi_term t;
00133 
00134   t=aim->a;
00135   deref_args(t,set_empty);
00136   warningflag = !warningflag;
00137 
00138   /*  RM: Sep 24 1993  */
00139   Infoline("*** Warning messages are%s printed\n",warningflag?"":" not");
00140   
00141   return TRUE;
00142 }
00143 
00144 /******** C_MAXINT
00145   Return the integer of greatest magnitude that guarantees exact
00146   integer arithmetic.
00147 */
00148 static long c_maxint()
00149 {
00150   ptr_psi_term t,result;
00151   REAL val;
00152   long num,success;
00153   
00154   t=aim->a;
00155   deref_args(t,set_empty);
00156   result=aim->b;
00157   deref_ptr(result);
00158   success=get_real_value(result,&val,&num);
00159   if (success) {
00160     if (num)
00161       success=(val==(REAL)WL_MAXINT);
00162     else
00163       success=unify_real_result(result,(REAL)WL_MAXINT);
00164   }
00165   return success;
00166 }
00167 
00168 
00169 
00170 /* 21.1 */
00171 /******** C_QUIET
00172   Return the value of not(NOTQUIET).
00173   */
00174 long c_quiet()
00175 {
00176   ptr_psi_term t,result,ans;
00177   int success=TRUE;
00178   
00179   t=aim->a;
00180   deref_args(t,set_empty);
00181   result=aim->b;
00182   deref_ptr(result);
00183   ans=stack_psi_term(4);
00184   ans->type = NOTQUIET ? false : true;
00185   push_goal(unify,result,ans,NULL);
00186   return success;
00187 }
00188 
00189 
00190 
00191 /******** C_CPUTIME
00192   Return the cpu-time in seconds used by the Wild_Life interpreter.
00193 */
00194 static long c_cputime()
00195 {
00196   ptr_psi_term result, t;
00197   REAL thetime,val;
00198   long num,success;
00199   
00200   t=aim->a;
00201   deref_args(t,set_empty);
00202   result=aim->b;
00203   deref_ptr(result);
00204   success=get_real_value(result,&val,&num);
00205   if (success) {
00206     times(&life_end);
00207 #ifndef OS2_PORT
00208     thetime=(life_end.tms_utime-life_start.tms_utime)/60.0;
00209 #else
00210     thetime=(life_end-life_start)/60.0;
00211 #endif
00212 
00213     if (num)
00214       success=(val==thetime);
00215     else
00216       success=unify_real_result(result,thetime);
00217   }
00218   return success;
00219 }
00220 
00221 /******** C_REALTIME
00222   Return the time in seconds since 00:00:00 GMT, January 1, 1970.
00223   This is useful for building real-time applications such as clocks.
00224 */
00225 static long c_realtime()
00226 {
00227   ptr_psi_term result, t;
00228   REAL thetime,val;
00229   long num,success;
00230 #ifndef OS2_PORT
00231   struct timeval tp;
00232   struct timezone tzp;
00233 #else
00234   time_t tp;
00235   float part_sec;
00236 #endif
00237   
00238   t=aim->a;
00239   deref_args(t,set_empty);
00240   result=aim->b;
00241   deref_ptr(result);
00242   success=get_real_value(result,&val,&num);
00243   if (success) {
00244 #ifndef OS2_PORT
00245     gettimeofday(&tp, &tzp);
00246     thetime=(REAL)tp.tv_sec + ((REAL)tp.tv_usec/1000000.0);
00247     /* thetime=times(&life_end)/60.0; */
00248 #else
00249     time(&tp);
00250     thetime = (REAL) tp;
00251 #endif
00252     if (num)
00253       success=(val==thetime);
00254     else
00255       success=unify_real_result(result,thetime);
00256   }
00257   return success;
00258 }
00259 
00260 /******** C_LOCALTIME
00261   Return a psi-term containing the local time split up into year, month, day,
00262   hour, minute, second, and weekday.
00263   This is useful for building real-time applications such as clocks.
00264 */
00265 static long c_localtime()
00266 {
00267   ptr_psi_term result, t, psitime;
00268   long success=TRUE;
00269 #ifndef OS2_PORT
00270   struct timeval tp;
00271   struct timezone tzp;
00272 #else
00273    time_t tp;
00274 #endif
00275   struct tm *thetime;
00276   
00277   t=aim->a;
00278   deref_args(t,set_empty);
00279   result=aim->b;
00280   deref_ptr(result);
00281 
00282 #ifndef OS2_PORT
00283   gettimeofday(&tp, &tzp);
00284   thetime=localtime((time_t *) &(tp.tv_sec));
00285 #else
00286   time(&tp);
00287   thetime = localtime((time_t *) &tp);
00288 #endif  
00289 
00290   psitime=stack_psi_term(4);
00291   psitime->type=timesym;
00292   stack_add_int_attr(psitime, year_attr,    thetime->tm_year+1900);
00293   stack_add_int_attr(psitime, month_attr,   thetime->tm_mon+1);
00294   stack_add_int_attr(psitime, day_attr,     thetime->tm_mday);
00295   stack_add_int_attr(psitime, hour_attr,    thetime->tm_hour);
00296   stack_add_int_attr(psitime, minute_attr,  thetime->tm_min);
00297   stack_add_int_attr(psitime, second_attr,  thetime->tm_sec);
00298   stack_add_int_attr(psitime, weekday_attr, thetime->tm_wday);
00299 
00300   push_goal(unify,result,psitime,NULL);
00301 
00302   return success;
00303 }
00304 
00305 /******** C_STATISTICS
00306   Print some information about Wild_Life: stack size, heap size, total memory.
00307 */
00308 static long c_statistics()
00309 {
00310   ptr_psi_term t;
00311   long success=TRUE;
00312   long t1,t2,t3;
00313 
00314   t=aim->a;
00315   deref_args(t,set_empty);
00316 
00317   t1 = sizeof(mem_base)*(stack_pointer-mem_base);
00318   t2 = sizeof(mem_base)*(mem_limit-heap_pointer);
00319   t3 = sizeof(mem_base)*(mem_limit-mem_base);
00320 
00321   printf("\n");
00322   /* printf("************** SYSTEM< INFORMATION **************\n"); */
00323   printf("Stack size  : %8d bytes (%5dK) (%ld%%)\n",t1,t1/1024,100*t1/t3);
00324   printf("Heap size   : %8d bytes (%5dK) (%ld%%)\n",t2,t2/1024,100*t2/t3);
00325   printf("Total memory: %8d bytes (%5dK)\n",t3,t3/1024);
00326 
00327 #ifdef X11
00328   printf("X predicates are installed.\n");
00329 #else
00330   printf("X predicates are not installed.\n");
00331 #endif
00332   
00333   /* printf("\n"); */
00334   /* printf("************************************************\n"); */
00335   return success;
00336 }
00337 
00338 
00339 /******** C_GARBAGE
00340   Force a call to the garbage collector.
00341 */
00342 static long c_garbage()
00343 {
00344   ptr_psi_term t;
00345 
00346   t=aim->a;
00347   deref_args(t,set_empty);
00348   garbage();
00349   return TRUE;
00350 }
00351 
00352 
00353 /******** C_GETENV
00354   Get the value of an environment variable.
00355 */
00356 static long c_getenv()
00357 {
00358   long success=FALSE;
00359   ptr_psi_term arg1,arg2,funct,result,t;
00360   int smaller;
00361   
00362   funct = aim->a;
00363   result=aim->b;
00364   deref_ptr(funct);
00365   deref_ptr(result);
00366   
00367   get_two_args(funct->attr_list, &arg1, &arg2);
00368   if(arg1) {
00369     deref_ptr(arg1);
00370     if(matches(arg1->type,quoted_string,&smaller) && arg1->value) {
00371       char *s=(char *)getenv((char *)arg1->value);
00372       if(s) {
00373         success=TRUE;
00374         t=stack_psi_term(4);
00375         t->type=quoted_string;
00376         t->value=(GENERIC)heap_copy_string(s);
00377         push_goal(unify,result,t,NULL);
00378       }
00379     }
00380     else
00381       Errorline("bad argument in %P\n",funct);
00382   }
00383   else
00384     Errorline("argument missing in %P\n",funct);
00385   
00386   return success;
00387 }
00388 
00389 
00390 /******** C_SYSTEM
00391   Pass a string to shell for execution. Return the value as the result.
00392 */
00393 static long c_system()
00394 {
00395   long success=TRUE;
00396   ptr_psi_term arg1,arg2,funct,result;
00397   REAL value;
00398   long smaller;
00399   
00400   funct=aim->a;
00401   deref_ptr(funct);
00402   result=aim->b;
00403   get_two_args(funct->attr_list,&arg1,&arg2);
00404   if(arg1) {
00405     deref(arg1);
00406     deref_args(funct,set_1);
00407     if((success=matches(arg1->type,quoted_string,&smaller)))
00408       if(arg1->value) {
00409         value=(REAL)system((char *)arg1->value);
00410         if(value==127) {
00411           success=FALSE;
00412           Errorline("could not execute shell in %P.\n",funct);
00413           /* report_error(funct,"couldn't execute shell"); */
00414         }
00415         else
00416           success=unify_real_result(result,value);
00417       }
00418       else {
00419         /* residuate(arg1); */ /*  RM: Feb 10 1993  */
00420         success=FALSE;
00421         Errorline("bad argument in %P.\n",funct);
00422       }
00423     else {
00424       success=FALSE;
00425       Errorline("bad argument in %P.\n",funct);
00426       /* report_error(funct,"bad argument"); */
00427     }
00428   }
00429   else
00430     curry();
00431   
00432   return success;
00433 }
00434 
00435 /******** C_ENCODE
00436   Force type encoding.
00437   This need normally never be called by the user.
00438 */
00439 static long c_encode()
00440 {
00441   ptr_psi_term t;
00442 
00443   t=aim->a;
00444   deref_args(t,set_empty);
00445   encode_types();
00446   return TRUE;
00447 }
00448 
00449 static GENERIC unitListElement;
00450 
00451 void setUnitList(x)
00452 GENERIC x;
00453 {
00454         unitListElement = x;
00455 }
00456 
00457 ptr_psi_term unitListValue()
00458 {
00459         return makePsiTerm((void *)unitListElement);
00460 }
00461 
00462 GENERIC unitListNext()
00463 {
00464         unitListElement = NULL;
00465         return NULL;
00466 }
00467 
00468 ptr_psi_term intListValue(p)
00469 ptr_int_list p;
00470 {
00471         return makePsiTerm((void *)p->value);
00472 }
00473 
00474 GENERIC intListNext(p)
00475 ptr_int_list p;
00476 {
00477         return (GENERIC )(p->next);
00478 }
00479 
00480 ptr_psi_term quotedStackCopy(p)
00481 ptr_psi_term p;
00482 {
00483         ptr_psi_term q;
00484 
00485         q = stack_copy_psi_term(p);
00486         mark_quote(q);
00487         return q;
00488 }
00489 
00490 /* Return a ptr to a psi-term marked as  evaluated.  The psi-term is a copy at
00491  * the top level of the goal residuated on p, with the rest of the psi-term
00492  * shared.
00493  */
00494 
00495 ptr_psi_term residListGoalQuote(p)
00496 ptr_residuation p;
00497 {
00498         ptr_psi_term psi;
00499 
00500         psi = stack_psi_term(4);
00501         copyPsiTerm(psi, p->goal->a);
00502         psi->status = 4;
00503         return psi;
00504 }
00505 
00506 GENERIC residListNext(p)
00507 ptr_residuation p;
00508 {
00509         return (GENERIC )(p->next);
00510 }
00511 
00512 ptr_psi_term makePsiTerm(x)
00513 ptr_definition x;
00514 {
00515         ptr_psi_term p;
00516         
00517         p = stack_psi_term(4);
00518         p->type = x;
00519         return p;
00520 }
00521 
00522 
00523 
00524 ptr_psi_term makePsiList(head, valueFunc, nextFunc)
00525      
00526      GENERIC head;
00527      ptr_psi_term (*valueFunc)();
00528      GENERIC (*nextFunc)();
00529 {
00530   ptr_psi_term result;
00531 
00532   
00533   /*  RM: Dec 14 1992: Added the new list representation  */
00534   result=stack_nil();
00535   
00536   while (head) {
00537     result=stack_cons((*valueFunc)(head),result);
00538     head=(*nextFunc)(head);
00539   }
00540   return result;
00541 }
00542 
00543 
00544 
00545 /******** C_ResidList
00546   rlist(A) ->  list all eval/prove goals residuated on variable 'A'.
00547 */
00548 static long c_residList()
00549 {
00550         ptr_psi_term func;
00551         ptr_psi_term result,arg1, other;
00552         
00553         func = aim->a;
00554         deref_ptr(func);
00555 
00556         get_one_arg(func->attr_list, &arg1);
00557         if (!arg1)
00558         {
00559                 curry();
00560                 return TRUE;
00561         }
00562         
00563         result = aim->b;
00564         deref(result);
00565         deref_ptr(arg1);
00566         deref_args(func, set_1);
00567 
00568         other = makePsiList((void *)arg1->resid,
00569                             residListGoalQuote,
00570                             residListNext);
00571         resid_aim = NULL;
00572         push_goal(unify,result,other,NULL);
00573         return TRUE;
00574 }
00575 
00576 
00577 ptr_goal makeGoal(p)
00578 ptr_psi_term p;
00579 {
00580         ptr_goal old = goal_stack;
00581         ptr_goal g;
00582         
00583         push_goal(prove, p, DEFRULES, NULL);
00584         g = goal_stack;
00585         g->next=NULL;
00586         goal_stack = old;
00587         return g;
00588 }
00589 
00590 
00591 /******** C_residuate
00592   residuate(A,B) ->  residuate goal B on variable A, non_strict in both args
00593 */
00594 static long c_residuate()
00595 {
00596         ptr_psi_term pred;
00597         ptr_psi_term arg1, arg2;
00598         ptr_goal g;
00599         
00600         pred = aim->a;
00601         deref_ptr(pred);
00602 
00603         get_two_args(pred->attr_list, &arg1, &arg2);
00604         if ((!arg1)||(!arg2)) {
00605           Errorline("%P requires two arguments.\n",pred);
00606           return FALSE;
00607         }
00608         
00609         deref_ptr(arg1);
00610         deref_ptr(arg2);
00611         deref_args(pred, set_1_2);
00612 
00613         g = makeGoal(arg2);
00614         residuateGoalOnVar(g, arg1, NULL);
00615         
00616         return TRUE;
00617 }
00618 
00619 /******** C_mresiduate
00620   Multiple-variable residuation of a predicate.
00621   mresiduate(A,B) ->  residuate goal B on a list of variables A, non_strict in
00622   both args.  If any of the variables is bound the predicate is executed.
00623   The list must have finite length.
00624 */
00625 static long c_mresiduate()
00626      
00627 {
00628   long success=TRUE;
00629   ptr_psi_term pred;
00630   ptr_psi_term arg1, arg2, tmp, var;
00631   ptr_goal g;
00632   
00633   pred = aim->a;
00634   deref_ptr(pred);
00635   
00636   get_two_args(pred->attr_list, &arg1, &arg2);
00637   if ((!arg1)||(!arg2)) {
00638     Errorline("%P requires two arguments.\n",pred);
00639     return FALSE;
00640   }
00641   
00642   deref_ptr(arg1);
00643   deref_ptr(arg2);
00644   deref_args(pred, set_1_2);
00645   
00646   g = makeGoal(arg2);
00647   
00648   /* Then residuate on all the list variables: */
00649   tmp=arg1;
00650   while(tmp && tmp->type==alist) { /*  RM: Dec 14 1992  */
00651     get_two_args(tmp->attr_list,&var,&tmp);
00652     if(var) {
00653       deref_ptr(var);
00654       residuateGoalOnVar(g,var,NULL);
00655     }
00656     if(tmp)
00657       deref_ptr(tmp);
00658   }
00659   
00660   if(!tmp || tmp->type!=nil) {
00661     Errorline("%P should be a nil-terminated list in mresiduate.\n",arg1);
00662     success=FALSE;
00663   }
00664 
00665   return success;
00666 }
00667 
00668 
00669 
00670 void insert_system_builtins()
00671 {
00672   new_built_in(bi_module,"trace",predicate,c_trace);
00673   new_built_in(bi_module,"step",predicate,c_step);
00674   new_built_in(bi_module,"verbose",predicate,c_verbose);
00675   new_built_in(bi_module,"warning",predicate,c_warning);
00676   new_built_in(bi_module,"maxint",function,c_maxint);
00677   new_built_in(bi_module,"cpu_time",function,c_cputime);
00678   new_built_in(bi_module,"quiet",function,c_quiet); /* 21.1 */
00679   new_built_in(bi_module,"real_time",function,c_realtime);
00680   new_built_in(bi_module,"local_time",function,c_localtime);
00681   new_built_in(bi_module,"statistics",predicate,c_statistics);
00682   new_built_in(bi_module,"gc",predicate,c_garbage);
00683   new_built_in(bi_module,"system",function,c_system);
00684   new_built_in(bi_module,"getenv",function,c_getenv);
00685   new_built_in(bi_module,"encode",predicate,c_encode);
00686   new_built_in(bi_module,"rlist",function,c_residList);
00687   new_built_in(bi_module,"residuate",predicate,c_residuate);
00688   new_built_in(bi_module,"mresiduate",predicate,c_mresiduate);
00689   new_built_in(bi_module,"tprove",predicate,c_tprove);
00690 }

Generated on Sat Jan 26 08:48:06 2008 for WildLife by  doxygen 1.5.4