struct lispobj *eval_let(struct lispobj *exps, struct lispobj *env) { struct lispobj *binds, *body, *vars, *vals, *lambda, *ret, *evals; binds = CAR(exps); body = CDR(exps); if(length(binds) > 0) { struct lispobj *tvars, *tvals; vars = heap_grab(NEW_CONS(NULL, NULL)); vals = heap_grab(NEW_CONS(NULL, NULL)); tvars = vars; tvals = vals; while(binds != NULL) { struct lispobj *bind = CAR(binds); if(length(bind) != 2) { ret = NEW_ERROR("Bad binding in the let exp.\n"); goto exit; } CAR(tvars) = heap_grab(CAR(bind)); CAR(tvals) = heap_grab(CADR(bind)); CDR(tvars) = heap_grab(NEW_CONS(NULL, NULL)); CDR(tvals) = heap_grab(NEW_CONS(NULL, NULL)); tvars = CDR(tvars); tvals = CDR(tvals); binds = CDR(binds); } tvars = NULL; tvals = NULL; } else { return NEW_ERROR("Empty bindgings in the let exp.\n"); } lambda = heap_grab(env_proc_make(vars, body, env)); evals = heap_grab(env_val_list(vals, env)); if(evals != NULL && OBJ_TYPE(evals) == ERROR) { ret = evals; } else { ret = apply(lambda, evals); heap_release(evals); } heap_release(lambda); exit: heap_release(vals); heap_release(vars); return ret; }
struct lispobj *subr_error(struct lispobj *args) { if(length(args) != 1) return ERROR_ARGS; struct lispobj *obj = CAR(args); if(OBJ_TYPE(obj) != STRING) return NEW_ERROR("Argument is not a string.\n"); return NEW_ERROR(STRING_VALUE(obj)); }
struct lispobj *apply(struct lispobj *proc, struct lispobj *args) { if(proc != NULL && OBJ_TYPE(proc) == CONS) { struct lispobj *ret; if(NEW_SYMBOL("SUBR") == CAR(proc)) { /* Apply primitive function. */ struct lispobj *body, *(*subr)(struct lispobj *); body = CADR(proc); subr = (struct lispobj *) NUMBER_VALUE(body); //subr = (struct lispobj *) body; ret = heap_grab(subr(args)); } else if(NEW_SYMBOL("PROC") == CAR(proc)) { /* Apply user defined procedure. */ struct lispobj *body, *params, *penv; body = CADDR(proc); params = CADR(proc); penv = CADDDR(proc); if(length(params) == length(args)) { struct lispobj *env; if(params == NULL || params == NEW_SYMBOL("NIL")) { env = penv; ret = eval_progn(body, env); } else { env = heap_grab(NEW_CONS(env_frame_make(params, args), penv)); ret = eval_progn(body, env); heap_release(env); } } else { char error[64]; snprintf(error, 64, "Has recieved wrong number of parameters: %d.\n", length(args)); ret = heap_grab(NEW_ERROR(error)); } } else { goto error; } return ret; } error: return heap_grab(NEW_ERROR("Unknown procedure.\n")); }
struct lispobj *subr_minus(struct lispobj *args) { if(length(args) == 0) return ERROR_ARGS; struct lispobj *num; char num_value[30]; snprintf(num_value, 30, "%d", NUMBER_VALUE(CAR(args))); num = NEW_NUMBER(num_value); args = CDR(args); if(args == NULL) { NUMBER_VALUE(num) = 0 - NUMBER_VALUE(num); } else { while(args != NULL) { if(CAR(args) != NULL && OBJ_TYPE(CAR(args)) == NUMBER) { NUMBER_VALUE(num) -= NUMBER_VALUE(CAR(args)); args = CDR(args); } else { object_delete(num); return NEW_ERROR("Argument is not a number.\n"); } } } return num; }
struct lispobj *env_var_lookup(struct lispobj *var, struct lispobj *env) { struct lispobj *frame, *cell; char error[64]; while(env != NULL) { frame = ENV_FIRST(env); while(frame != NULL) { cell = CAR(frame); if(CAR(cell) == var) { /* Return whole cell, e.g. (foo . 1). */ return cell; } frame = CDR(frame); } env = ENV_REST(env); } snprintf(error, 64, "Unbound variable: %s.\n", SYMBOL_VALUE(var)); return NEW_ERROR(error); }
static struct lispobj* eval_cond(struct lispobj *exps, struct lispobj *env) { struct lispobj *ret = OBJ_FALSE; if(exps != NULL) { struct lispobj *cond; cond = CAR(exps); if(cond != NULL && OBJ_TYPE(cond) == CONS) { struct lispobj *pred; pred = eval(CAR(cond), env); if(pred != NULL && OBJ_TYPE(pred) == ERROR) { ret = pred; } else { if(pred) { if(length(cond) == 1) { ret = OBJ_TRUE; } else { ret = eval(CADR(cond), env); } } else { ret = eval_cond(CDR(exps), env); } heap_release(pred); } } else { ret = NEW_ERROR("Bad cond clause.\n"); } } return ret; }
struct lispobj *env_var_define(struct lispobj *var, struct lispobj *val, struct lispobj *env) { struct lispobj *frame, *pair, *cell, *lookup; /* Checking on variable existence. */ lookup = env_var_lookup(var, env); /* If variable exists return error. */ if(OBJ_TYPE(lookup) != ERROR) { char error[64]; snprintf(error, 64, "Variable already exists: %s.\n", SYMBOL_VALUE(var)); return NEW_ERROR(error); } /* Remove not necessary object. */ heap_release(lookup); /* Get top frame from environment. */ frame = ENV_FIRST(env); /* Creating cell for new variable. */ cell = NEW_CONS(var, val); /* Appending new cell into the frame. */ pair = NEW_CONS(cell, frame); frame = heap_grab(pair); /* Appending the frame into the environment. */ CAR(env) = frame; return val; }
int SocketUDP::send(const char* buf, int len) { int r; r = SocketWrapper::_sendto(_socket, buf, len, 0, (struct sockaddr*) &_addr, _addrsize); if (r == SOCKET_ERROR) { _lastError = SocketWrapper::_getlasterror(); NEW_ERROR(E_SOCKET_SEND, SocketWrapper::_errorMessage(_lastError)); } return r; }
int SocketUDP::leaveGroup() { int r; r = SocketWrapper::_dropmembership(_socket,&_mreq); if (r != 0) { _lastError = SocketWrapper::_getlasterror(); NEW_ERROR(E_SOCKET_SETSOCKOPT, SocketWrapper::_errorMessage(_lastError)); } return r; }
struct lispobj *subr_cdr(struct lispobj *args) { if(length(args) != 1) return ERROR_ARGS; struct lispobj *obj = CAR(args); if(obj == NULL || OBJ_TYPE(obj) != CONS) { return NEW_ERROR("Argument is not a CONS type.\n"); } return CDR(obj); }
int SocketUDP::joinGroup(const IPv4& ip) { _mreq.imr_multiaddr.s_addr = inet_addr(_ip.getString().c_str()); _mreq.imr_interface.s_addr = htonl(INADDR_ANY); int r; r = SocketWrapper::_addmembership(_socket,&_mreq); if (r != 0) { _lastError = SocketWrapper::_getlasterror(); NEW_ERROR(E_SOCKET_SETSOCKOPT, SocketWrapper::_errorMessage(_lastError)); } return r; }
int SocketUDP::recv(char* buf, int len) { int result; result = SocketWrapper::_recvfrom(_socket, buf, len); if (result == 0) { _lastError = SocketWrapper::_getlasterror(); // conexo finalizada de forma amigável NEW_WARNING(E_SOCKET_RECV, SocketWrapper::_errorMessage(_lastError)); } else if (result < 0) { _lastError = SocketWrapper::_getlasterror(); NEW_ERROR(E_SOCKET_RECV, SocketWrapper::_errorMessage(_lastError)); } return result; }
struct lispobj *subr_divide(struct lispobj *args) { if(length(args) < 2) return ERROR_ARGS; if(CAR(args) == NULL || OBJ_TYPE(CAR(args)) != NUMBER) { return NEW_ERROR("Argument is not a number.\n"); } struct lispobj *num = CAR(args); args = CDR(args); while(args != NULL) { if(CAR(args) != NULL && OBJ_TYPE(CAR(args)) == NUMBER) { NUMBER_VALUE(num) /= NUMBER_VALUE(CAR(args)); args = CDR(args); } else { object_delete(num); return NEW_ERROR("Argument is not a number.\n"); } } return num; }
struct lispobj *subr_load(struct lispobj* args) { if(length(args) != 1) return ERROR_ARGS; struct lispobj *obj = CAR(args); if(obj == NULL || OBJ_TYPE(obj) != STRING) { return NEW_ERROR("Argument is not a string.\n"); } if(!load(STRING_VALUE(obj))) return OBJ_FALSE; return OBJ_TRUE; }
struct lispobj *subr_apply(struct lispobj *args) { if(length(args) != 2) return ERROR_ARGS; struct lispobj *proc, *params; proc = CAR(args); params = CADR(args); if((proc != NULL && OBJ_TYPE(proc) != CONS) || (params != NULL && OBJ_TYPE(params) != CONS)) { return NEW_ERROR("Wrong arguments type.\n"); } return apply(proc, params); }
struct lispobj *subr_multi(struct lispobj *args) { struct lispobj *num; num = NEW_NUMBER("1"); while(args != NULL) { if(CAR(args) != NULL && OBJ_TYPE(CAR(args)) == NUMBER) { NUMBER_VALUE(num) *= NUMBER_VALUE(CAR(args)); args = CDR(args); } else { object_delete(num); return NEW_ERROR("Argument is not a number.\n"); } } return num; }
struct lispobj *env_var_assign(struct lispobj *var, struct lispobj *val, struct lispobj *env) { struct lispobj *cell; if(var == NULL || OBJ_TYPE(var) != SYMBOL) { return NEW_ERROR("Variable name is not a symbol.\n"); } /* Checking on variable existence. */ cell = env_var_lookup(var, env); /* If variable not exists return error. */ if(OBJ_TYPE(cell) == ERROR) { return cell; } /* Remove old value. */ heap_release(CDR(cell)); /* Assign new value. */ CDR(cell) = heap_grab(val); return val; }
struct lispobj *subr_mod(struct lispobj *args) { if(length(args) != 2) return ERROR_ARGS; struct lispobj *number, *div; number = CAR(args); div = CADR(args); if(OBJ_TYPE(number) == NUMBER && OBJ_TYPE(div) == NUMBER) { char mod[30]; snprintf(mod, 30, "%d", NUMBER_VALUE(number) % NUMBER_VALUE(div)); return NEW_NUMBER(mod); } else { return NEW_ERROR("Arguments must be numbers.\n"); } }
struct lispobj *subr_compar(struct lispobj *args) { if(length(args) != 2) return ERROR_ARGS; struct lispobj *obj1, *obj2; obj1 = CAR(args); obj2 = CADR(args); if(obj1 != NULL && obj2 != NULL) { if(OBJ_TYPE(obj1) == NUMBER && OBJ_TYPE(obj2) == NUMBER) { if(NUMBER_VALUE(obj1) == NUMBER_VALUE(obj2)) return OBJ_TRUE; } else { return NEW_ERROR("Arguments must be a number.\n"); } } return OBJ_FALSE; }
int DecodeVideo::decode(uint8_t * input, unsigned int size, unsigned int timestamp, queue_t * outQueue, bool * gotFrame, QueueExtraData * extraData) { if (!(_flags & FLAG_OPENED)) { NEW_ERROR(E_DECODE_NOT_OPENED, ""); return -1; } if (!outQueue || !input || !size) { NEW_ERROR(E_COMMON_NULL_PARAMETER, "outQueue | input | size"); return -1; } uint32_t inbufSize = size; uint8_t * outbuf; int gotFrameInt; int outbufSize; QueueExtraDataVideo extraNew; if (gotFrame) { *gotFrame = false; } // só pode começar a decodificação em um quadro I if (_needFrameI) { if (_IsFrameI(&input, &inbufSize)) { _needFrameI = false; } else { NEW_WARNING(E_DECODE_WAITING_FRAME_I, "Aguardando um frame I"); return -1; } } // fica decodificando o buffer até que encontre um frame completo ou até // que acabe o buffer disponível _codecCtxMutex.lock(); int usedTotal = 0; while ((uint32_t)usedTotal < inbufSize) { AVPacket packet; av_init_packet(&packet); packet.data = input + usedTotal; packet.size = inbufSize - usedTotal; gotFrameInt = 0; int used = avcodec_decode_video2(_codecCtx, _tempFrame, &gotFrameInt, &packet); usedTotal += used; // se já usou todo buffer mas não completou o frame, tenta decodificar de novo o mesmo // buffer pra tentar pegar o frame. isso é necessário ao decodificar mpeg4 if (usedTotal == inbufSize && !gotFrameInt && used >= 0) { used = avcodec_decode_video2(_codecCtx, _tempFrame, &gotFrameInt, &packet); } av_free_packet(&packet); if (used < 0) { NEW_ERROR(E_DECODE_VIDEO, "Falha decodificando video."); _codecCtxMutex.unlock(); return -1; } if (gotFrameInt) { // pegou frame completo! break; } } _codecCtxMutex.unlock(); // guarda variável de saída if (gotFrame) { *gotFrame = (gotFrameInt != 0); } // se não pegou um frame inteiro nem prossegue... retorna o que usou do buffer if (!(*gotFrame)) { return -1; } // desentrelaçamento, conversão de pix_fmt, cópia para o buffer de saída outbufSize = _PrepareFrame(_tempFrame, &outbuf); if (outbufSize <= 0) { return -1; } // coloca os dados na queue // obs: só coloca se pegou um frame inteiro extraNew =_UpdateExtraData((QueueExtraDataVideo *)extraData); #ifdef ANDROID if(queue_length(outQueue) < 5){ if (queue_enqueue(outQueue, outbuf, outbufSize, timestamp, &extraNew) != E_OK) { queue_dealloc(outbuf); NEW_ERROR(E_DECODE_ENQUEUE, ""); return -1; } } else { queue_dealloc(outbuf); } #else if (queue_enqueue(outQueue, outbuf, outbufSize, timestamp, &extraNew) != E_OK) { queue_dealloc(outbuf); NEW_ERROR(E_DECODE_ENQUEUE, ""); return -1; } #endif return usedTotal; }
error calc(int x, int y, int& result) { return NEW_ERROR(error::unknown_error); }