Guest User

Untitled

a guest
Apr 27th, 2017
581
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 11.61 KB | None | 0 0
  1. /* Scheme In One Defun, but in C this time.
  2.  
  3.  *                    COPYRIGHT (c) 1988-1994 BY                            *
  4.  *        PARADIGM ASSOCIATES INCORPORATED, CAMBRIDGE, MASSACHUSETTS.       *
  5.  *        See the source file SLIB.C for more information.                  *
  6.  
  7. */
  8.  
  9. /*
  10.  
  11.  
  12. Paradigm Associates Inc          Phone: 617-492-6079
  13. 29 Putnam Ave, Suite 6
  14. Cambridge, MA 02138
  15.  
  16.   */
  17.  
  18. /***************************************************************/
  19. /* This has been modified to act as an interface to siod as an */
  20. /* embedded Lisp module.                                       */
  21. /* Also a (large) number of other functions have been added    */
  22. /*                                                             */
  23. /*    Alan W Black ([email protected]) 8th April 1996          */
  24. /***************************************************************/
  25. #include <cstdio>
  26. #include "EST_unix.h"
  27. #include <cstdlib>
  28. #include <cstring>
  29. #include "EST_String.h"
  30. #include "EST_THash.h"
  31. #include "EST_StringTrie.h"
  32. #include "EST_cutils.h"
  33. #include "EST_strcasecmp.h"
  34. #include "siod.h"
  35. #include "siodp.h"
  36. #include "siodeditline.h"
  37.  
  38. #ifdef EST_SIOD_ENABLE_PYTHON
  39. #include "slib_python.h"
  40. #endif
  41.  
  42. extern "C" const char * repl_prompt;
  43.  
  44. template <> EST_String EST_THash<EST_String, EST_Regex *>::Dummy_Key = "DUMMY";
  45. template <> EST_Regex *EST_THash<EST_String, EST_Regex *>::Dummy_Value = NULL;
  46.  
  47. #if defined(INSTANTIATE_TEMPLATES)
  48. #include "../base_class/EST_THash.cc"
  49.  
  50.   Instantiate_TStringHash_T(EST_Regex *, hash_string_regex)
  51. #endif
  52.  
  53. static EST_TStringHash<EST_Regex *> regexes(100);
  54.  
  55. int siod_init(int heap_size)
  56. {
  57.     /* Initialize siod */
  58.     int actual_heap_size;
  59.  
  60.     if (heap_size == -1)  // unspecified by user
  61.     {
  62.     char *char_heap_size=getenv("SIODHEAPSIZE");
  63.     if ((char_heap_size == 0) ||
  64.         (atoi(char_heap_size) < 1000))
  65.         actual_heap_size=ACTUAL_DEFAULT_HEAP_SIZE;
  66.     else
  67.         actual_heap_size=atoi(char_heap_size);
  68.     }
  69.     else
  70.     actual_heap_size = heap_size;
  71.  
  72.     init_storage(actual_heap_size);
  73.     init_subrs();
  74.  
  75.     #ifdef EST_SIOD_ENABLE_PYTHON
  76.     init_subrs_python();
  77.     #endif
  78.  
  79.     return 0;
  80. }
  81.  
  82. void siod_tidy_up()
  83. {
  84.     #ifdef EST_SIOD_ENABLE_PYTHON
  85.     python_tidy_up();
  86.     #endif
  87.  
  88.     close_open_files();
  89. }
  90.  
  91. LISP siod_get_lval(const char *name,const char *message)
  92. {
  93.     // returns value of variable name.  If not set gives an error
  94.     LISP iii, rval=NIL;
  95.  
  96.     iii = rintern(name);
  97.  
  98.     // value or NIL if unset
  99.     if (symbol_boundp(iii,current_env) == NIL)
  100.     {
  101.     if (message != NULL)
  102.         err(message,iii);
  103.     }
  104.     else
  105.     rval = symbol_value(iii, current_env);
  106.  
  107.     return rval;
  108. }
  109.  
  110. LISP siod_set_lval(const char *name,LISP val)
  111. {
  112.     // set variable name to val
  113.     LISP iii, rval;
  114.    
  115.     iii = rintern(name);
  116.  
  117.     rval = setvar(iii,val,current_env);
  118.  
  119.     return rval;
  120. }
  121.  
  122. LISP siod_assoc_str(const char *key,LISP alist)
  123. {
  124.     // assoc without going through LISP atoms
  125.     // made get_c_string inline for optimization
  126.     LISP l,lc,lcc;
  127.  
  128.     for (l=alist; CONSP(l); l=CDR(l))
  129.     {
  130.     lc = CAR(l);
  131.     if (CONSP(lc))
  132.     {
  133.         lcc = CAR(lc);
  134.         if (NULLP(lcc)) continue;
  135.         else if TYPEP(lcc,tc_symbol)
  136.         {
  137.         if (strcmp(key,PNAME(lcc))==0)
  138.             return lc;
  139.         }
  140.         else if TYPEP(lcc,tc_flonum)
  141.         {
  142.         if (FLONMPNAME(lcc) == NULL)
  143.         {
  144.             char b[TKBUFFERN];
  145.             sprintf(b,"%g",FLONM(lcc));
  146.             FLONMPNAME(lcc) = (char *)must_malloc(strlen(b)+1);
  147.             sprintf(FLONMPNAME(lcc),"%s",b);
  148.         }
  149.         if (strcmp(key,FLONMPNAME(lcc))==0)
  150.             return lc;
  151.         }
  152.         else if TYPEP(lcc,tc_string)
  153.         {
  154.         if (strcmp(key,lcc->storage_as.string.data)==0)
  155.             return lc;
  156.         }
  157.         else
  158.         continue;
  159.     }
  160.     }
  161.     return NIL;
  162. }
  163.  
  164. LISP siod_member_str(const char *key,LISP list)
  165. {
  166.     // member without going through LISP atoms
  167.     LISP l;
  168.  
  169.     for (l=list; CONSP(l); l=CDR(l))
  170.     if (strcmp(key,get_c_string(CAR(l))) == 0)
  171.         return l;
  172.  
  173.     return NIL;
  174. }
  175.  
  176. LISP siod_regex_member_str(const EST_String &key,LISP list)
  177. {
  178.     // Check the regexs in LIST against key
  179.     LISP l;
  180.  
  181.     for (l=list; CONSP(l); l=CDR(l))
  182.     if (key.matches(make_regex(get_c_string(CAR(l)))))
  183.         return l;
  184.  
  185.     return NIL;
  186. }
  187.  
  188. LISP siod_member_int(const int key,LISP list)
  189. {
  190.     // member without going through LISP atoms
  191.     LISP l;
  192.  
  193.     for (l=list; CONSP(l); l=CDR(l))
  194.     if (key == get_c_int(CAR(l)))
  195.         return l;
  196.     return NIL;
  197. }
  198.      
  199. int siod_llength(LISP list)
  200. {
  201.     // length of string;
  202.     int len;
  203.     LISP l;
  204.  
  205.     for (len=0,l=list; CONSP(l); l=CDR(l),len++);
  206.    
  207.     return len;
  208.  
  209. }
  210.  
  211. LISP siod_nth(int n,LISP list)
  212. {
  213.     // nth member -- first member is 0;
  214.     int i;
  215.     LISP l;
  216.  
  217.     for (i=0,l=list; CONSP(l); l=CDR(l),i++)
  218.     if (i == n)
  219.         return car(l);
  220.    
  221.     return NIL;
  222.  
  223. }
  224.  
  225. int siod_atomic_list(LISP list)
  226. {
  227.     // TRUE is list only contains atoms
  228.     LISP p;
  229.  
  230.     for (p=list; p != NIL; p=cdr(p))
  231.     if (CONSP(car(p)))
  232.         return FALSE;
  233.  
  234.     return TRUE;
  235. }
  236.  
  237. int siod_eof(LISP item)
  238. {
  239.     // TRUE if item is what siod denotes as eof
  240.     if (CONSP(item) &&
  241.     (cdr(item) == NIL) &&
  242.     (SYMBOLP(car(item))) &&
  243.     (strcmp("eof",get_c_string(car(item))) == 0))
  244.     return TRUE;
  245.     else
  246.     return FALSE;
  247. }
  248.  
  249. LISP quote(LISP l)
  250. {
  251.     // Add quote round a Lisp expression
  252.     return cons(rintern("quote"),cons(l,NIL));
  253. }
  254.  
  255. LISP siod_last(LISP list)
  256. {
  257.     LISP l;
  258.  
  259.     if ((list == NIL) || (NCONSP(list)))
  260.     return NIL;
  261.     else
  262.     {
  263.     for (l=list; cdr(l) != NIL; l=cdr(l));
  264.     return l;
  265.     }
  266. }
  267.  
  268. int get_param_int(const char *name, LISP params, int defval)
  269. {
  270.     // Look up name in params and return value if present or
  271.     // defval if not present
  272.     LISP pair;
  273.  
  274.     pair = siod_assoc_str(name,params);
  275.  
  276.     if (pair == NIL)
  277.     return defval;
  278.     else  if FLONUMP(car(cdr(pair)))
  279.     return (int)FLONM(car(cdr(pair)));
  280.     else
  281.     {
  282.     cerr << "param " << name << " not of type int" << endl;
  283.     err("",NIL);
  284.     return -1;
  285.     }
  286.  
  287. }
  288.  
  289. float get_param_float(const char *name, LISP params, float defval)
  290. {
  291.     // Look up name in params and return value if present or
  292.     // defval if not present
  293.     LISP pair;
  294.  
  295.     pair = siod_assoc_str(name,params);
  296.  
  297.     if (pair == NIL)
  298.     return defval;
  299.     else  if (FLONUMP(car(cdr(pair))))
  300.     return (float)FLONM(car(cdr(pair)));
  301.     else
  302.     {
  303.     cerr << "param " << name << " not of type float" << endl;
  304.     err("",NIL);
  305.     return -1;
  306.     }
  307.  
  308. }
  309.  
  310. const char *get_param_str(const char *name, LISP params, const char *defval)
  311. {
  312.     // Look up name in params and return value if present or
  313.     // defval if not present
  314.     LISP pair;
  315.  
  316.     pair = siod_assoc_str(name,params);
  317.  
  318.     if (pair == NIL)
  319.     return defval;
  320.     else
  321.     return get_c_string(car(cdr(pair)));
  322. }
  323.  
  324. LISP get_param_lisp(const char *name, LISP params, LISP defval)
  325. {
  326.     // Look up name in params and return value if present or
  327.     // defval if not present
  328.     LISP pair;
  329.  
  330.     pair = siod_assoc_str(name,params);
  331.  
  332.     if (pair == NIL)
  333.     return defval;
  334.     else
  335.     return car(cdr(pair));
  336. }
  337.  
  338. LISP make_param_str(const char *name,const char *val)
  339. {
  340.     return cons(rintern(name),cons(rintern(val),NIL));
  341. }
  342.  
  343. LISP make_param_int(const char *name, int val)
  344. {
  345.     return cons(rintern(name),cons(flocons(val),NIL));
  346. }
  347.  
  348. LISP make_param_float(const char *name, float val)
  349. {
  350.     return cons(rintern(name),cons(flocons(val),NIL));
  351. }
  352.  
  353. LISP make_param_lisp(const char *name,LISP val)
  354. {
  355.     return cons(rintern(name),cons(val,NIL));
  356. }
  357.  
  358. EST_Regex &make_regex(const char *r)
  359. {
  360.     // Return pointer to existing regex if its already been created
  361.     // otherwise create a new one for this r.
  362.     EST_Regex *rx;
  363.     EST_String sr = r;
  364.     int found;
  365.  
  366.     rx = regexes.val(sr,found);
  367.     if (!found)
  368.     {
  369.     rx = new EST_Regex(r);
  370.     regexes.add_item(sr,rx);
  371.     }
  372.  
  373.     return *rx;
  374. }
  375.  
  376. LISP apply_hooks(LISP hooks,LISP arg)
  377. {
  378.     //  Apply each function in hooks to arg returning value from
  379.     // final application (or arg itself)
  380.     LISP h,r;
  381.  
  382.     r = arg;
  383.    
  384.     if (hooks && (!CONSP(hooks)))  // singleton
  385.     r = leval(cons(hooks,cons(quote(arg),NIL)),NIL);
  386.     else
  387.     for (h=hooks; h != NIL; h=cdr(h))
  388.         r = leval(cons(car(h),cons(quote(arg),NIL)),NIL);
  389.     return r;
  390. }
  391.  
  392. LISP apply_hooks_right(LISP hooks,LISP args)
  393. {
  394.     // The above version neither quotes its arguments properly of deals
  395.     // with lists of arguments so here's a better one
  396.     //  Apply each function in hooks to arg returning value from
  397.     // final application (or arg itself)
  398.     LISP h,r;
  399.  
  400.     if (hooks == NIL)
  401.     r = args;
  402.     else if (!CONSP(hooks))  // singleton
  403.     r = apply(hooks,args);
  404.     else
  405.     for (r=args,h=hooks; h != NIL; h=cdr(h))
  406.         r = apply(car(h),r);
  407.     return r;
  408. }
  409.  
  410. LISP apply(LISP func,LISP args)
  411. {
  412.     LISP qa,a;
  413.  
  414.     for (qa=NIL,a=args; a; a=cdr(a))
  415.     qa = cons(quote(car(a)),qa);
  416.     return leval(cons(func,reverse(qa)),NIL);
  417. }
  418.  
  419. LISP stringexplode(const char *str)
  420. {
  421.     // Explode character string into list of symbols one for each char
  422.     LISP l=NIL;
  423.     unsigned int i;
  424.     char id[2];
  425.     id[1] = '\0';
  426.  
  427.     for (i=0; i < strlen(str); i++)
  428.     {
  429.     id[0] = str[i];
  430.     l = cons(rintern(id),l);
  431.     }
  432.  
  433.     return reverse(l);
  434. }
  435.  
  436. /* Editline completion functions */
  437.    
  438. char **siod_variable_generator(char *text,int length)
  439. {
  440.     LISP l,lmatches;
  441.     const char *name;
  442.     char **matches = NULL;
  443.     int i;
  444.  
  445.     /* Return the next name which partially matches from the command list. */
  446.     for(lmatches=NIL,l=oblistvar;CONSP(l);l=CDR(l))
  447.     {
  448.     if (VCELL(car(l)) == NIL) continue;
  449.     switch(TYPE(VCELL(CAR(l))))
  450.     {
  451.       case tc_subr_0:
  452.       case tc_subr_1:
  453.       case tc_subr_2:
  454.       case tc_subr_3:
  455.       case tc_subr_4:
  456.       case tc_lsubr:
  457.       case tc_fsubr:
  458.       case tc_msubr:
  459.       case tc_closure:
  460.         continue;
  461.       default:
  462.             /* only return names of nonfunctions (sometimes too restrictive) */
  463.         name = PNAME(CAR(l));
  464.         if (strncmp(name, text, length) == 0)
  465.         lmatches = cons(CAR(l),lmatches);
  466.     }
  467.     }
  468.  
  469.     /* Need to return the matches in a char** */
  470.     matches = walloc(char *,siod_llength(lmatches)+1);
  471.     for (l=lmatches,i=0; l; l=cdr(l),i++)
  472.     matches[i] = wstrdup(PNAME(car(l)));
  473.     matches[i] = NULL;
  474.  
  475.     return matches;
  476. }
  477.  
  478. char **siod_command_generator (char *text,int length)
  479. {
  480.     LISP l,lmatches;
  481.     const char *name;
  482.     char **matches = NULL;
  483.     int i;
  484.  
  485.     /* Return the next name which partially matches from the command list. */
  486.     for(lmatches=NIL,l=oblistvar;CONSP(l);l=CDR(l))
  487.     {
  488.     if (VCELL(car(l)) == NIL) continue;
  489.     switch(TYPE(VCELL(CAR(l))))
  490.     {
  491.       case tc_subr_0:
  492.       case tc_subr_1:
  493.       case tc_subr_2:
  494.       case tc_subr_3:
  495.       case tc_subr_4:
  496.       case tc_lsubr:
  497.       case tc_fsubr:
  498.       case tc_msubr:
  499.       case tc_closure:
  500.             /* only return names of functions */
  501.         name = PNAME(CAR(l));
  502.         if (strncmp(name, text, length) == 0)
  503.         lmatches = cons(CAR(l),lmatches);
  504.       default: continue;
  505.     }
  506.     }
  507.  
  508.     /* Need to return the matches in a char** */
  509.     matches = walloc(char *,siod_llength(lmatches)+1);
  510.     for (l=lmatches,i=0; l; l=cdr(l),i++)
  511.     matches[i] = wstrdup(PNAME(car(l)));
  512.     matches[i] = NULL;
  513.  
  514.     return matches;
  515. }
  516.  
  517. void siod_list_to_strlist(LISP l, EST_StrList &a)
  518. {
  519.     // copy l into a
  520.     LISP b;
  521.  
  522.     a.clear();
  523.  
  524.     for (b=l; b != NIL; b=cdr(b))
  525.     a.append(get_c_string(car(b)));
  526.  
  527. }
  528.  
  529. LISP siod_strlist_to_list(EST_StrList &a)
  530. {
  531.     // copy a into l
  532.     LISP b=NIL;;
  533.     EST_Litem *p;
  534.  
  535.     for (p=a.head(); p != 0; p=p->next())
  536.     b = cons(rintern(a(p)),b);
  537.  
  538.     return reverse(b);
  539. }
Advertisement
Add Comment
Please, Sign In to add comment