示例#1
0
文件: cell.c 项目: mitchan0321/toy
Cell*
cell_add_str(Cell *p, const char *src) {
    int len;

    if (NULL == p) return NULL;

    len = strlen(src)+1;
    if ((len + p->length) > p->allocsize) {
	if (NULL == cell_realloc(p, len + p->length))
	    return NULL;
    }

    strncpy(&p->data[p->length], src, len);
    p->length = p->length + len-1;

    return p;
}
示例#2
0
文件: cell.c 项目: mitchan0321/toy
Cell*
cell_add_char(Cell *p, const char src) {
    int len;

    if (NULL == p) return NULL;

    len = 2;
    if ((len + p->length) > p->allocsize) {
	if (NULL == cell_realloc(p, len + p->length))
	    return NULL;
    }

    p->data[p->length] = src;
    p->data[p->length+1] = 0;
    p->length = p->length + len-1;

    return p;
}
示例#3
0
文件: reader.c 项目: 8l/bomberjacket
ReaderState* read_char(char c, ReaderState* rs) {
  Cell* cell = rs->cell;
  Cell* new_cell;

  if (!cell) {
    // make a root
    cell = alloc_nil();
    cell->next = alloc_nil();
    *rs->stack = cell;
  }

  if (rs->state == PST_ATOM) {
    if (c==' ' || c==13 || c==10) {
      // skip whitespace
    } else if (c==';') {
      // comment
      rs->state = PST_COMMENT;
    } else if (c>='0' && c<='9') {
      rs->state = PST_NUM;
      rs->valuestate = VST_DEFAULT;
      new_cell = alloc_int(0);
      new_cell->value = c-'0';
      cell->addr = new_cell;

    } else if (c=='(') {
      // start list
      new_cell = alloc_nil();
      cell->addr = new_cell;
      *rs->stack = cell;

      cell = new_cell;
      rs->stack++;
      rs->level++;
      rs->state = PST_ATOM;
    } else if (c==')') {
      // end of list
      cell = reader_end_list(cell, rs);
    } else if (c=='[') { 
      // bytes (hex notation)
      rs->state = PST_BYTES;
      rs->sym_len = 0;
      new_cell = alloc_bytes();
      cell->addr = new_cell;
    } else if (c=='"') {
      // string
      rs->state = PST_STR;
      rs->sym_len = 0;
      new_cell = alloc_string();
      cell->addr = new_cell;
    } else {
      // symbol
      rs->state = PST_SYM;
      rs->sym_len = 1;
      new_cell = alloc_sym(0);
      new_cell->addr = cell_malloc(SYM_INIT_BUFFER_SIZE);
      memset(new_cell->addr, 0, SYM_INIT_BUFFER_SIZE);
      ((char*)new_cell->addr)[0] = c;
      new_cell->size = SYM_INIT_BUFFER_SIZE; // buffer space
      cell->addr = new_cell;
    }

  } else if (rs->state == PST_COMMENT) {
    //printf("c[%c]\n",c);
    if (c=='\n' || c=='0') {
      rs->state = PST_ATOM;
    }
  } else if (rs->state == PST_NUM || rs->state == PST_NUM_NEG) {
    if (c>='0' && c<='9' || ((rs->valuestate == VST_HEX && c>='a' && c<='f'))) {
      // build number
      Cell* vcell = (Cell*)cell->addr;
      int mul = 10;
      if (rs->valuestate == VST_HEX) mul = 16;
      int d = 0;
      if (c>='a') {
        d = 10+(c-'a');
      } else {
        d = c-'0';
      }
      
      if (rs->state == PST_NUM_NEG) {
        vcell->value = vcell->value*mul - d;
      } else {
        vcell->value = vcell->value*mul + d;
      }
    } else if (c==' ' || c==13 || c==10) {
      cell = reader_next_list_cell(cell, rs);
    } else if (c==')') {
      cell = reader_end_list(cell, rs);
    } else if (c=='x') {
      rs->valuestate = VST_HEX;
    } else {
      rs->state = PST_ERR_UNEXP_JUNK_IN_NUMBER;
    }
  } else if (rs->state == PST_SYM || rs->state == PST_STR) {

    int append = 0;

    if (rs->state == PST_STR) {
      if (c=='"') {
        // string is over
        Cell* vcell = (Cell*)cell->addr;
        vcell->size = (rs->sym_len);
        cell = reader_next_list_cell(cell, rs);
      } else {
        append = 1;
      }
    }
    else {
      if (c==')') {
        cell = reader_end_list(cell, rs);
      } else if (c==' ' || c==13 || c==10) {
        cell = reader_next_list_cell(cell, rs);
      } else if (rs->state == PST_SYM && (c>='0' && c<='9')) {
        Cell* vcell = (Cell*)cell->addr;
        // detect negative number
        if (((char*)vcell->addr)[0] == '-') {
          // we're actually not a symbol, correct the cell.
          rs->state = PST_NUM_NEG;
          vcell->tag = TAG_INT;
          vcell->value = -(c-'0');
        }
      } else {
        append = 1;
      }
    }

    if (append) {
      // build symbol/string
      Cell* vcell = (Cell*)cell->addr;
      int idx = rs->sym_len;
      rs->sym_len++;
      if (rs->sym_len>=vcell->size-1) {
        // grow buffer
        vcell->addr = cell_realloc(vcell->addr, vcell->size, 2*vcell->size);
        memset(vcell->addr+vcell->size, 0, vcell->size);
        vcell->size = 2*vcell->size;
      }
      ((char*)vcell->addr)[idx] = c;
    }

  } else if (rs->state == PST_BYTES) {
    if (c==']') {
      Cell* vcell = (Cell*)cell->addr;
      vcell->size = (rs->sym_len)/2;
      cell = reader_next_list_cell(cell, rs);
    } else if ((c>='0' && c<='9') || (c>='a' && c<='f') || (c>='A' && c<='F')) {
      int n = c;
      if (n>='a') n-=('a'-'9'-1); // hex 'a' to 10 offset
      if (n>='A') n-=('A'-'9'-1); // hex 'a' to 10 offset
      n-='0'; // char to value

      Cell* vcell = (Cell*)cell->addr;
      int idx = rs->sym_len;
      rs->sym_len++;
      if (rs->sym_len>=(vcell->size/2)-1) {
        // grow buffer
        vcell->addr = cell_realloc(vcell->addr, vcell->size, 2*vcell->size); // TODO: check the math
        memset(vcell->addr+vcell->size, 0, vcell->size);
        vcell->size = 2*vcell->size;
      }
      if (idx%2==0) { // even digit
        ((byte*)vcell->addr)[idx/2] = n<<4; // high nybble
      } else { // odd digit
        ((byte*)vcell->addr)[idx/2] |= n;
      }
      
    } else if (c==' ' || c==13 || c==10) {
      // skip
    } else {
      rs->state = PST_ERR_UNEXP_JUNK_IN_BYTES;
    }
  }
  rs->cell = cell;
  return rs;
}