Пример #1
0
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;
}
Пример #2
0
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));
}
Пример #3
0
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"));
}
Пример #4
0
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;
}
Пример #5
0
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);
}
Пример #6
0
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;
}
Пример #7
0
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;
}
Пример #8
0
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;
}
Пример #9
0
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;
}
Пример #10
0
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);
}
Пример #11
0
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;
}
Пример #12
0
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;
}
Пример #13
0
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;
}
Пример #14
0
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;
}
Пример #15
0
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);
}
Пример #16
0
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;
}
Пример #17
0
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;
}
Пример #18
0
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");
    }

}
Пример #19
0
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;
}
Пример #20
0
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;
}
Пример #21
0
error calc(int x, int y, int& result) {
    return NEW_ERROR(error::unknown_error);
}