// Create either a static or an uncounted string. // Diffrence between static and uncounted is in the lifetime // of the string. Static are alive for the lifetime of the process. // Uncounted are not ref counted but will be deleted at some point. ALWAYS_INLINE StringData* StringData::MakeShared(StringSlice sl, bool trueStatic) { if (UNLIKELY(sl.len > StringData::MaxSize)) { throw_string_too_large(sl.len); } auto const cc = CapCode::ceil(sl.len); auto const need = cc.decode() + kCapOverhead; auto const sd = static_cast<StringData*>( trueStatic ? low_malloc(need) : malloc(need) ); auto const data = reinterpret_cast<char*>(sd + 1); sd->m_data = data; auto const count = trueStatic ? StaticValue : UncountedValue; sd->m_hdr.init(cc, HeaderKind::String, count); sd->m_len = sl.len; // m_hash is computed soon. data[sl.len] = 0; auto const mcret = memcpy(data, sl.ptr, sl.len); auto const ret = reinterpret_cast<StringData*>(mcret) - 1; // Recalculating ret from mcret avoids a spill. ret->preCompute(); // get m_hash right assert(ret == sd); assert(ret->isFlat()); assert(trueStatic ? ret->isStatic() : ret->isUncounted()); assert(ret->checkSane()); return ret; }
// add last cons_t *add_list(cons_t *l, int type, consvalue_t v){ cons_t *top; if(l == NULL){ l = (cons_t *)low_malloc(sizeof(cons_t)); top = l; }else{ top = l; while(l->cdr != NULL) l = l->cdr; l->cdr = (cons_t *)low_malloc(sizeof(cons_t)); l = l->cdr; } l->type = type; l->v = v; l->cdr = NULL; return top; }
cons_t *create_list(Token *token) { cons_t *list = NULL; consvalue_t value; value.i = 0; while(next_token(token)){ switch(token->type){ case TOKEN_BRACE_OPEN: value.car = create_list(token); list = add_list(list, TYPE_CAR, value); break; case TOKEN_INT: value.i = token->num; list = add_list(list, TYPE_INT, value); break; case TOKEN_STR: if(strcmp(token->str, "if") == 0){ list = add_list(list, TYPE_IF, value); }else if(strcmp(token->str, "t") == 0){ list = add_list(list, TYPE_T, value); }else if(strcmp(token->str, "nil") == 0){ list = add_list(list, TYPE_NIL, value); }else if(strcmp(token->str, "setq") == 0){ list = add_list(list, TYPE_SETQ, value); }else if(strcmp(token->str, "defun") == 0){ list = add_list(list, TYPE_DEFUN, value); }else{ // variable or function ? int length = strlen(token->str); value.str = (char *)low_malloc(length+1); strcpy(value.str, token->str); list = add_list(list, TYPE_STR, value); } break; case TOKEN_OPERATE: list = add_list(list, token->num, value); break; case TOKEN_BRACE_CLOSE: goto end; default: printf("PARSER ERROR!!\n"); goto end; } } end: return list; }
Func *add_function(char *name, cons_t *arg, Code *code, int code_index) { Func *f = (Func *)low_malloc(sizeof(Func)); f->name = name; f->arg = arg; f->code = code; f->code_index = code_index; // count f->arg_count = 0; while(arg != NULL){ f->arg_count++; arg = arg->cdr; } f->next = funclist; funclist = f; return f; }
// create either a static or an uncounted string. // Diffrence between static and uncounted is in the lifetime // of the string. Static are alive for the lifetime of the process. // Uncounted are not ref counted but will be deleted at some point. ALWAYS_INLINE StringData* StringData::MakeShared(StringSlice sl, bool trueStatic) { if (UNLIKELY(sl.len > StringData::MaxSize)) { throw_string_too_large(sl.len); } auto const cc = CapCode::ceil(sl.len); auto const need = cc.decode() + kCapOverhead; auto const sd = static_cast<StringData*>( trueStatic ? low_malloc(need) : malloc(need) ); auto const data = reinterpret_cast<char*>(sd + 1); sd->m_data = data; sd->m_hdr.init(cc, HeaderKind::String, 0); sd->m_lenAndHash = sl.len; // hash=0 data[sl.len] = 0; auto const mcret = memcpy(data, sl.ptr, sl.len); auto const ret = reinterpret_cast<StringData*>(mcret) - 1; // Recalculating ret from mcret avoids a spill. assert(ret->m_hash == 0); assert(ret->getCount() == 0); if (trueStatic) { ret->setStatic(); } else { ret->setUncounted(); } assert(ret == sd); assert(ret->isFlat()); assert(trueStatic ? ret->isStatic() : ret->isUncounted()); assert(ret->checkSane()); return ret; }
// create either a static or an uncounted string. // Diffrence between static and uncounted is in the lifetime // of the string. Static are alive for the lifetime of the process. // Uncounted are not ref counted but will be deleted at some point. StringData* StringData::MakeShared(StringSlice sl, bool trueStatic) { if (UNLIKELY(sl.len > StringData::MaxSize)) { throw_string_too_large(sl.len); } auto const encodable = roundUpPackedCap(sl.len); auto const need = encodable + kCapOverhead; auto const sd = static_cast<StringData*>( trueStatic ? low_malloc(need) : malloc(need) ); auto const data = reinterpret_cast<char*>(sd + 1); auto const capCode = packedCapToCode(encodable); sd->m_data = data; sd->m_capAndCount = HeaderKind::String << 24 | capCode; // count=0 sd->m_lenAndHash = sl.len; // hash=0 data[sl.len] = 0; auto const mcret = memcpy(data, sl.ptr, sl.len); auto const ret = reinterpret_cast<StringData*>(mcret) - 1; // Recalculating ret from mcret avoids a spill. assert(ret->m_hash == 0); assert(ret->m_count == 0); if (trueStatic) { ret->setStatic(); } else { ret->setUncounted(); } assert(ret == sd); assert(ret->isFlat()); assert(trueStatic ? ret->isStatic() : ret->isUncounted()); assert(ret->checkSane()); return ret; }