Esempio n. 1
0
/* "Cons" operation */
long
l_cons(long car, long cdr)
{
  int s;

  if (t_cons_free < 0){   /*  no cons cells */
    if (gc_protect(car) < 0)
      return -1;
    if (gc_protect(cdr) < 0)
      return -1;
    gcollect();           /* invoke garbage collector */
    gc_unprotect(cdr);
    gc_unprotect(car);
  }

  /* get a free cons cell from a free list */
  s = t_cons_free;
  if (t_cons_car[t_cons_free] != t_cons_free)
    t_cons_free  = t_cons_car[t_cons_free];  /* next free cell */
  else
    t_cons_free = -1;                        /* self-loop: end of free list */

  /* constract a new cell */
  t_cons_car[s] = car;
  t_cons_cdr[s] = cdr;

  return (TAG_CONS | s);
}
Esempio n. 2
0
/* Evaluate arguments */
long
eval_args(long func, long arg, long av[2], int n)
{
  long  x, y;

  if ((n != FTYPE_ANY_ARGS) && (n != list_len(arg)))
    return err_msg(errmsg_ill_nargs, 1, func);

  switch (n){

  case 0:
    av[0] = TAG_NIL;
    break;

  case 1:
    if ((av[0] = l_eval(l_car(arg))) < 0)
      return -1;
    break;

  case 2:
    if ((av[0] = l_eval(l_car(arg))) < 0)
      return -1;
    if (gc_protect(av[0]) < 0)
      return -1;
    if ((av[1] = l_eval(l_car(l_cdr(arg)))) < 0)
      return -1;
    gc_unprotect(av[0]);
    break;

  case FTYPE_ANY_ARGS:   /* return evaluated arguments as a list */
    if (D_GET_TAG(arg) != TAG_CONS){
      av[0] = TAG_NIL;
    } else {
      if ((x = l_eval(l_car(arg))) < 0)
        return -1;
      if ((av[0] = y = l_cons(x, TAG_NIL)) < 0)
        return -1;
      if (gc_protect(av[0]) < 0)
        return -1;
      for (arg = l_cdr(arg); D_GET_TAG(arg) == TAG_CONS; arg = l_cdr(arg)){
        if ((x = l_eval(l_car(arg))) < 0)
          return -1;
        rplacd(y, l_cons(x, TAG_NIL)); 
        y = l_cdr(y);
      }
      gc_unprotect(av[0]);
    }
  }
  return av[0];
}
Esempio n. 3
0
/* Compile a string */
void compile_string(compiler_type *comp_void, char *str, bool include_baselib) {
  compiler_core_type *compiler = (compiler_core_type *)comp_void;
  ins_stream_type *baselib = 0; /* TODO: should be gc root */
  char path[PATH_MAX];

  /* Actually parse the input stream. */
  yylex_init_extra(compiler, &(compiler->scanner));
  yy_scan_string(str, compiler->scanner);

  /* TODO: Need a better way to handle GC than leaking */
  gc_protect(compiler->gc);

  /* Inject include for base library */
  if (include_baselib) {
    strcpy(path, compiler->home);
    strcat(path, "/lib/baselib.scm");

    STREAM_NEW(baselib, string, path);
    setup_include(compiler, baselib); 
  }
  
  parse_internal(compiler, compiler->scanner);
  
  gc_unprotect(compiler->gc);

  yylex_destroy(compiler->scanner);
}
Esempio n. 4
0
/* Top level */
void
toplevel(void)
{
  long  s, v;

  for (;;){
    t_stack_ptr = 0;
    printf("\n] ");             /* prompt */
    if ((s = l_read()) < 0)     /* read */
      continue;
    if (s == TAG_EOF)           /* end of file */
      break;
    if (gc_protect(s) < 0)
      break;
    if ((v = l_eval(s)) < 0)    /* eval */
      continue;
    gc_unprotect(s);
        printf("\n");
    (void) l_print(v);          /* print */
  }
}
Esempio n. 5
0
/* Compile a file */
void compile_file(compiler_type *comp_void, char *file_name, bool include_baselib) {
  compiler_core_type *compiler = (compiler_core_type *)comp_void;
  ins_stream_type *baselib = 0; /* TODO: should be gc root */
  FILE *in = 0;
  char path[PATH_MAX];

  /* Actually parse the input stream. */
  yylex_init_extra(compiler, &(compiler->scanner));

  in = fopen(file_name, "r");
  if (!in) {
    (void)fprintf(stderr, "Error %i while attempting to open '%s'\n",
      errno, file_name);
      assert(0);
  }

  //yyset_in(in, compiler->scanner);
  yy_switch_to_buffer(
    yy_create_buffer(in, YY_BUF_SIZE, compiler->scanner), compiler->scanner);

  push_include_path(compiler, file_name);

  /* TODO: Need a better way to handle GC than leaking */
  gc_protect(compiler->gc);

  /* Inject include for base library */
  if (include_baselib) {
    strcpy(path, compiler->home);
    strcat(path, "/lib/baselib.scm");

    STREAM_NEW(baselib, string, path);
    setup_include(compiler, baselib); 
  }
  
  parse_internal(compiler, compiler->scanner);
  
  gc_unprotect(compiler->gc);

  yylex_destroy(compiler->scanner);
}
Esempio n. 6
0
/* Read an S-expression */
long
l_read(void)
{
  long  s, v, t;
  char  token[32];
  char  ch, i;
  
  /* skip spaces */
  if ((ch = skip_space()) < 0){  /* eof */
    return TAG_EOF; 

  } else if (ch == ';'){         /* comment */
    while (gchar() != '\n')
      ;
    return -1;
  }
#ifdef ZX81
  else if (ch == '\"'){        /* quote macro */
#else
  else if (ch == '\''){        /* quote macro */
#endif
    if ((t = l_read()) < 0)
      return -1;
    if (t == TAG_EOF)
      return err_msg(errmsg_eof, 0, 0);
    t = l_cons(t, TAG_NIL);
    s = l_cons((TAG_SYMB|KW_QUOTE), t);

  } else if (ch != '('){         /* t, nil, symbol, or integer */
    token[0] = ch;
    for (i = 1; ; i++){
      ch = gchar();
      if (isspace(ch) || iscntrl(ch) || (ch < 0) 
          || (ch == ';') || (ch == '(') || (ch == ')')){
        ugchar(ch);
        token[i] = '\0';
        
        /*  Changed to permint the definition of "1+" and "1-" */
        if ((isdigit((char)token[0]) && (token[1] != '+') && (token[1] != '-'))
/*        if (isdigit((char)token[0]) */
            || ((token[0] == '-') && isdigit((char)token[1]))
            || ((token[0] == '+') && isdigit((char)token[1]))){   /* integer */
          s = int_make_l(atol(token));
#ifdef SCHEME
        } else if (strcmp(token, "#f") == 0){                   /* nil */ 
          s = TAG_NIL;
        } else if (strcmp(token, "#t") == 0){                     /* t */
          s = TAG_T;
#else
        } else if (strcmp(token, "nil") == 0){                   /* nil */ 
          s = TAG_NIL;
        } else if (strcmp(token, "t") == 0){                     /* t */
          s = TAG_T;
#endif
        } else {                                                 /* symbol */
          s = TAG_SYMB | symb_make(token);
        }
        break;
      }
      token[i] = ch;
    }

  } else /* ch == '(' */ {       /* list */
    if ((ch = skip_space()) < 0){
      return err_msg(errmsg_eof, 0, 0);
    } else if (ch == ')'){
      s = TAG_NIL;  /* "()" = nil */
    } else {
      ugchar(ch);
      if ((t = l_read()) < 0)
        return err_msg(errmsg_eof, 0, 0);
      if (t == TAG_EOF)
        return -1;
      if ((s = v = l_cons(t, TAG_NIL)) < 0)
        return -1;
      if (gc_protect(s) < 0)
        return -1;
      for (;;){
        if ((ch = skip_space()) < 0)  /* look ahead next char */
          return err_msg(errmsg_eof, 0, 0);
        if (ch == ')')
          break;
        ugchar(ch);
        if ((t = l_read()) < 0)
          return -1;
        if (t == TAG_EOF)
          return err_msg(errmsg_eof, 0, 0);
        if ((t = l_cons(t, TAG_NIL)) < 0) 
          return -1;
        rplacd(v, t);
        v = l_cdr(v);
      }
      gc_unprotect(s);
    }
  }

  return s;
}

char
skip_space(void)
{
  char ch;

  for (;;){
    if ((ch = gchar()) < 0)
      return -1;     /* end-of-file */
    if (!isspace(ch) && !iscntrl(ch))
      break;
  }
  return ch;
}