Beispiel #1
0
static void solve_R1(float p[3], float q[3], 
		     float p2[3],float q2[3],
		     float p_scale, Matrix  R1)	       
{
    Matrix T, S;

    // Construct two local coordinate systems
    // and find the transformation between them
    make_frame(p,  p_scale, q,  T, 1);
    make_frame(p2, p_scale, q2, S, 0);
    rmatmult(R1,T,S);
}
Beispiel #2
0
void send_command(HANDLE * fd, struct receive_tcp_frame * tcp_frame)
{
    struct api_frame frm;
    struct api_at_command cmd;
    char frame_buffer[BUF_SIZE];
    size_t frame_size;
	#ifdef _DEBUG_
    int i;
	#endif
    /* Prepare Cmd */
    cmd.frame_id = tcp_frame->frame_id;
    cmd.command[0] = tcp_frame->command[0];
    cmd.command[1] = tcp_frame->command[1];
    memcpy(cmd.parameter, tcp_frame->data, tcp_frame->data_size);
    cmd.size = tcp_frame->data_size;
    /* Prepare Frame */
    frm.cmdid = 0x08;
    /* Build Frame Data */
    make_frame_data_at_command(&cmd, &frm);
    frame_size=make_frame(&frm, (uint8_t*)frame_buffer, BUF_SIZE);
    /* Send Frame */
    ERR(writeComm(fd, (uint8_t*)frame_buffer, frame_size), "write");
    #ifdef _DEBUG_
    fprintf(stderr, "DEBUG: Sent XBee frame [");
    for(i = 0 ; i < frame_size; ++i)
        fprintf(stderr, "%02X ", frame_buffer[i]);
    fprintf(stderr, "]\n");
    #endif
}
Beispiel #3
0
machine *make_machine()
{
    machine *ret = NEW(machine);
    ret->base_frame = make_frame(NULL,
                                 make_table(),
                                 make_table(), make_table(), NULL, PAUSE);
    incref(ret->base_frame);

    ret->current_frame = ret->base_frame;
    incref(ret->current_frame);

    ret->now = ret->base_frame;
    incref(ret->now);

    ret->accumulator = NULL;
    ret->paused = 0;

    ret->trace = make_stack_trace(arg("bottom-of-the-barrel"),
                                  NULL,
                                  NULL);
    incref(ret->trace);


    add_builtins(ret);
    add_builtin_numbers(ret);
    add_builtin_strings(ret);
    add_builtin_files(ret);

    return ret;
}
Beispiel #4
0
void send_to_frame(int fd, uint8_t * data, size_t size)
{
    struct api_frame frm, frm2;
    struct api_transmit_64 trans;
    uint8_t frame_buffer[BUF_SIZE];
    size_t frame_size;
    int i;
    //Prepare Trans
    memcpy(trans.dest_address, broadcast_address_64, 8);
    trans.frame_id = 20;
    trans.options = 0;
    memcpy(trans.rf_data, data, (size>100?100:size));
    trans.size = (size>100?100:size);
    //Prepare Frame
    frm.cmdid = 0x00;
    //Build frame data
    make_frame_data_transmit_64(&trans, &frm);
    frame_size=make_frame(&frm, frame_buffer, BUF_SIZE);
    //Send Frame
    ERR(write(fd, frame_buffer, frame_size), "write");
    cut_frame(frame_buffer, frame_size, &frm2);
    printf("Frame sent rsize %i size %i id %2X checksum %2X\nData:", frame_size, frm2.size, frm2.cmdid, frm2.checksum);
    for(i = 0; i < frm2.data_size; ++i)
        printf("%2X,", frm2.data[i]);
    printf("\n");

}
Beispiel #5
0
void push_instruction_list(machine * m,
                           oyster * ins,
                           table * scope, table * scope_below)
{
    incref(ins);

    frame *top = NULL;
    frame **cur = &top;
    while (!nilp(ins)) {
        (*cur) = make_frame(NULL,
                            scope, NULL, scope_below, car(ins), EVALUATE);
        incref(*cur);

        cur = &((*cur)->below);

        oyster *ins2 = cdr(ins);
        incref(ins2);
        decref(ins);
        ins = ins2;
    }

    decref(ins);
    (*cur) = m->current_frame;
    m->current_frame = top;
}
Beispiel #6
0
static frame make_lknv_frame(frame f, int n, int copy, rtype type)
{
    char v[8];
    string dv;

    if (copy)
    {
	frame cf = make_frame(f->type, NULL, f->cl, f->code, "");

	f = cf;
    }

    if (f->type == T_SLOT)
	return make_knv_frame(f, n);

    sprintf(v, "_v%c%d", LVAC, n);
    dv = make_decl(type, v);
    dv[0] = type;

    if (f->block)
    {
	int b = f->block;

	f = deblock_frame(f, 1);
	if (b != -1)
	    f = prepare_frame(f, type);
    }
    else if (f->type != type)
	f = coerce_frame(f, type);
    
    f->decls = cons(dv, f->decls);

    return merge_frames(T_CBOOL, T_UNKNOWN, f, NULL, f->cl + 18,
			"_lkn(" AMP, v, ", ", NORET(f->code), ")", "");
}
Beispiel #7
0
/**
 * @brief Connects the client to the server.
 * @param QString host - the host name
 * @param int port - the port used by the server
 * @param QString pseudo - the client's name
 */
void MainWindow::serverConnection(QString host, int port, QString pseudo)
{
    strcpy(_player.name, pseudo.toStdString().c_str());
    init_host(_ptr_host, (char*)host.toStdString().c_str(), &_local_addr);
    assign_port(&_local_addr, port);

    _player.socket = create_socket();

    // Have to test if the client can be connect to the server
    if(server_connection(_player.socket, _local_addr) >= 0) {

        qDebug() << "[Server_connection] : Client is connected";

        startListeners(); // Have to start listeners threads

        // Ask to the server to add the new client into its array of players
        qDebug() << "[Server_connection] : Sending information to the server" << _player.name;
        frame f = make_frame(_local_addr.sin_addr, _local_addr.sin_addr, CONNECT, _player.name);
        write_to_server(_player.socket, &f);

        // When the client is connected, display the mainPage of the application
        ui->stackedWidget->slideInIdx(1, SlidingStackedWidget::BOTTOM2TOP);
    }
    else {
        //Connection is impossible
        QMessageBox errorBox(QMessageBox::Question,tr("error"),tr("Can't establish the connection with the server."),QMessageBox::Cancel);
        errorBox.exec();
    }

}
Beispiel #8
0
static frame make_knv_frame(frame f, int n)
{
    frame fc = make_frame(f->type, copy_list(f->decls, 0), 6, "_knv(" AMP, "");
    char v[8], buf[512];
    int i, l;
    string dv, st, next;

    sprintf(v, "_v%c%d", LVAC, n);
    dv = make_decl(T_ATOM, v);

    for (i = 0, st = f->code; ; st = next + 1) {
	next = strchr(st, NSTC);
	l = next ? next - st : strlen(st);

	strncpy(buf + i, st, l);
	i += l;
	strcpy(buf + i, ", ");
	i += 2;

	if (!next) break;
    }
    strcpy(buf + i, "NULL)");
    i += 5;

    fc->decls = cons(dv, fc->decls);
    
    return merge_frames(T_CBOOL, T_UNKNOWN, fc, NULL, fc->cl + i + 9,
		        fc->code, v, ", ", buf, "");
}
Beispiel #9
0
void send_to_frame(HANDLE * fd, struct receive_tcp_frame * tcp_frame)
{
    struct api_frame frm;
    struct api_transmit_64 trans;
    char frame_buffer[BUF_SIZE];
    size_t frame_size;
	#ifdef _DEBUG_
    int i;
	#endif
    /* Prepare Trans */
    memcpy(trans.dest_address, tcp_frame->address, 8);
    trans.frame_id = tcp_frame->frame_id;
    trans.options = 0;
    memcpy(trans.rf_data, tcp_frame->data, (tcp_frame->data_size>100?100:tcp_frame->data_size));
    trans.size = (tcp_frame->data_size>100?100:tcp_frame->data_size);
    /* Prepare Frame */
    frm.cmdid = 0x00;
    /* Build frame data */
    make_frame_data_transmit_64(&trans, &frm);
    frame_size=make_frame(&frm, (uint8_t*)frame_buffer, BUF_SIZE);
    /* Send Frame */
    ERR(writeComm(fd, (uint8_t*)frame_buffer, frame_size), "write");
    #ifdef _DEBUG_
    fprintf(stderr, "DEBUG: Sent XBee frame [");
    for(i = 0 ; i < frame_size; ++i)
        fprintf(stderr, "%02X ", frame_buffer[i]);
    fprintf(stderr, "]\n");
    #endif
}
Beispiel #10
0
void main()
{
 //制作游戏窗口
 make_frame();
 //开始游戏
 start_game();
}
Beispiel #11
0
item extend_environment(item unev, item argl, item env){
	if (length(unev) == length(argl)){
		return cons(make_frame(unev, argl), env);
	}
	else{
		fprintf(stderr, "Too many or too few arguments supplied");
		exit(1);
	}
}
Beispiel #12
0
void push_new_instruction(machine * m, oyster * instruction, int flag)
{
    frame *t = m->current_frame;
    m->current_frame = make_frame(t,
                                  m->now->scope,
                                  m->now->scope_to_be,
                                  m->now->scope_below, instruction, flag);
    incref(m->current_frame);
    decref(t);
}
Beispiel #13
0
/**
 * @brief Sends to the server the message to send to all clients.
 * This message is formatted like that : "[player_name] : msg".
 * @param QString msg - the message to send.
 */
void MainWindow::sendChatMessage(QString msg)
{
    qDebug() << msg;
    char data[DATA_SIZE] = "\0";
    strcat(data, "[");
    strcat(data, _player.name);
    strcat(data, "] : ");
    strcat(data, msg.toStdString().c_str());
    frame f = make_frame(_local_addr.sin_addr, _local_addr.sin_addr, SEND_MSG_CHAT, data);
    write_to_server(_player.socket, &f);
}
Beispiel #14
0
data_t *extend_environment(const data_t *vars, const data_t *vals, data_t *env) {
	int lvars = length(vars), lvals = length(vals);
	if(lvars == lvals)
		return cons(make_frame(vars, vals), env);

	if(lvars < lvals) {
		printf("Too many arguments supplied. (Expected %d, got %d)\n", lvars, lvals);
		return make_symbol("error");
	} else {
		printf("Too few arguments supplied (Expected %d, got %d)\n", lvars, lvals);
		return make_symbol("error");
	}
}
PVideoFrame __stdcall LSMASHVideoSource::GetFrame( int n, IScriptEnvironment *env )
{
    uint32_t sample_number = n + 1;     /* For L-SMASH, sample_number is 1-origin. */
    codec_configuration_t *config = &vdh.config;
    config->lh.priv = env;
    if( config->error )
        return env->NewVideoFrame( vi );
    if( libavsmash_get_video_frame( &vdh, sample_number, vi.num_frames ) < 0 )
        return env->NewVideoFrame( vi );
    PVideoFrame as_frame;
    if( make_frame( &voh, config->ctx, vdh.frame_buffer, as_frame, env ) < 0 )
        env->ThrowError( "LSMASHVideoSource: failed to make a frame." );
    return as_frame;
}
Beispiel #16
0
void execute(Chunk *chunk) {
    Closure *closure = make_closure(chunk);
    Frame *frame = make_frame(NULL, closure);
    VM *vm = make_vm(frame, 0);

    execute_function(vm);

    gc(vm);
    free(vm);

    // TODO - free last closure [?]
    // Other closrues should be already taken care of
    // by the last gc sweep, but this one existed outside
    // of the heap.
}
Beispiel #17
0
frame make_cmp_frame(frame f1, frame f2, string op, rtype type, int l,
		     int trsl, int abs)
{
    rtype num = num_type(type) ? type : common_num_type(f1->type, f2->type);

    if (trsl && (!det_type(f1->type) || !det_type(f2->type) ||
		 f1->block == -1 || f2->block == -1))
    {
	if (det_type(f1->type))
	    f1 = prepare_frame(f1, num);
	if (det_type(f2->type))
	    f2 = prepare_frame(f2, num);

	return make_trsl_frame(f1, f2, num,
			       num == T_NUMBER ? 
   			           (abs ? merge_fainfix_strings :
				          merge_finfix_strings) :
			           merge_infix_strings,
			       op);
    }

    f1 = prepare_frame(f1, num);
    f2 = prepare_frame(f2, num);
    f1->code = NORET(f1->code);
    f2->code = NORET(f2->code);
    
    if (num == T_NUMBER)
    {
	int n = isnum(f2->code) << 1;
	string mop = n ? " - " : " - (";
	string cp = n ? "" : ")";

	if (abs)
	    f1 = merge_frames(num, num, f1, f2, f1->cl + f2->cl + 12 + n,
			      "fabs(", f1->code, mop, f2->code, ")", cp, "");
	else
	    f1 = merge_frames(num, num, f1, f2, f1->cl + f2->cl + 5 + n,
			      f1->code, mop, f2->code, cp, "");

	f2 = make_frame(num, NULL, l_epsilon + 1, epsilon, "");
    }

    return merge_frames(type == T_UNKNOWN ? num : type, num, f1, f2,
			f1->cl + f2->cl + l, RET, 
			f1->code, op, f2->code, "");
}
Beispiel #18
0
static void coerce_arg(rtype type, rtype ftype, int l, string code,
		       string *buf, int *i, int *lbuf,
		       int int_allowed, frame name)
{
    frame f = make_frame(type, NULL, l, code, "");

    if ((type == T_INTNUM || type == T_INTLNG) && !int_allowed)
	f = coerce_frame(f, T_NUMBER);

    f = coerce_frame(f, ftype);
    if (f->decls)
	name->decls = nconc(name->decls, copy_list(f->decls, 0));

    NORET(f->code);
    *buf = copy_into_buf(*buf, f->code, i, lbuf, strlen(f->code));

    mcfree(f->code);
    mcfree(f);
}
static const VSFrameRef *VS_CC vs_filter_get_frame( int n, int activation_reason, void **instance_data, void **frame_data, VSFrameContext *frame_ctx, VSCore *core, const VSAPI *vsapi )
{
    if( activation_reason != arInitial )
        return NULL;
    lsmas_handler_t *hp = (lsmas_handler_t *)*instance_data;
    VSVideoInfo     *vi = &hp->vi;
    uint32_t sample_number = MIN( n + 1, vi->numFrames );   /* For L-SMASH, sample_number is 1-origin. */
    libavsmash_video_decode_handler_t *vdhp = hp->vdhp;
    libavsmash_video_output_handler_t *vohp = hp->vohp;
    if( libavsmash_video_get_error( vdhp ) )
    {
        vsapi->setFilterError( "lsmas: failed to output a video frame.", frame_ctx );
        return NULL;
    }
    /* Set up VapourSynth error handler. */
    vs_basic_handler_t vsbh = { 0 };
    vsbh.out       = NULL;
    vsbh.frame_ctx = frame_ctx;
    vsbh.vsapi     = vsapi;
    lw_log_handler_t *lhp = libavsmash_video_get_log_handler( vdhp );
    lhp->priv     = &vsbh;
    lhp->show_log = set_error;
    /* Get and decode the desired video frame. */
    vs_video_output_handler_t *vs_vohp = (vs_video_output_handler_t *)vohp->private_handler;
    vs_vohp->frame_ctx = frame_ctx;
    vs_vohp->core      = core;
    vs_vohp->vsapi     = vsapi;
    if( libavsmash_video_get_frame( vdhp, vohp, sample_number ) < 0 )
    {
        vsapi->setFilterError( "lsmas: failed to output a video frame.", frame_ctx );
        return NULL;
    }
    /* Output video frame. */
    AVFrame    *av_frame = libavsmash_video_get_frame_buffer( vdhp );
    VSFrameRef *vs_frame = make_frame( vohp, av_frame );
    if( !vs_frame )
    {
        vsapi->setFilterError( "lsmas: failed to output a video frame.", frame_ctx );
        return NULL;
    }
    set_frame_properties( vdhp, vi, av_frame, vs_frame, sample_number, vsapi );
    return vs_frame;
}
Beispiel #20
0
static frame prepare_trsl_frame(frame f, frame knv, string trcb)
{
    string trq;
    string trce = strchr(trcb + 1, TRLC);
    int l = trcb - f->code;

    trcb[0] = trce[0] = '\0';

    trq = strrchr(f->code, QSMC);
    trq[-1] = '\0';

    knv = knv ? merge_frames(T_UNKNOWN, T_UNKNOWN, knv, NULL,
			     knv->cl + l + 8, 
			     knv->code, " " AMP AMP " " NST TABS,
			     f->code, "") :
		make_frame(T_UNKNOWN, NULL, l + 1, f->code, "");

    f = merge_frames(T_UNKNOWN, T_UNKNOWN, f, NULL, trce - trcb, trcb + 1, "");

    return knv;
}
Beispiel #21
0
/**
 * @brief Disconnects the client from the server.
 * @pre The client have to be connected before to call this method.
 */
void MainWindow::serverDisconnection()
{
    // cleaning the gui
    ui->connectionWidget->clean();
    ui->rightMenuWidget->clear();
    ui->checkerboardwidget->clear();

    frame f ;
    //Advise the opponent if the client is in a game
    if(strlen(_opponent_player.name) != 0) {
        qDebug() << "PPPPPPPPPPPPPPPPPPPPP I'm quit the game";
        strcpy(f.data_type, OPPONENT_QUIT);
        memcpy(f.data, &_opponent_player, sizeof(_opponent_player));
        write_to_server(_player.socket, &f);
    }


    //Advising the server for the disconnection
    f = make_frame(_local_addr.sin_addr, _local_addr.sin_addr, DISCONNECT, _player.name);
    write_to_server(_player.socket,&f);

    //disconnection of the client
    server_disconnection(_player.socket);


    stopListeners(); // Stop all listeners threads

    qDebug() << "Client is disconnected";

    // When the client is disconnected, display the connection page
    ui->stackedWidget->slideInIdx(0, SlidingStackedWidget::TOP2BOTTOM);

    strcpy(_player.name, "");
    _player.color = 0;
    strcpy(_opponent_player.name, "");
    _opponent_player.color = 0;



}
Beispiel #22
0
object_t *extend_environment(object_t *vars, object_t *vals,
                                 object_t *env) {
    return cons(make_frame(vars, vals), env);
}
Beispiel #23
0
 /** Run alignment algorithm.
 \param first_last Last aligned position in first sequence (output)
 \param second_last Last aligned position in second sequence (output)
 */
 void align(int& first_last, int& second_last) const {
     adjust_matrix_size();
     limit_range();
     make_frame();
     ASSERT_TRUE(!local() || max_errors() == -1);
     int& r_row = first_last;
     int& r_col = second_last;
     r_row = r_col = -1;
     for (int row = 0; row <= max_row(); row++) {
         int start_col = min_col(row);
         int stop_col = max_col(row);
         int min_score_col = start_col;
         for (int col = start_col; col <= stop_col; col++) {
             ASSERT_TRUE(col >= 0 && col < side());
             ASSERT_TRUE(in(row, col));
             int match = at(row - 1, col - 1) +
                         substitution(row, col);
             int gap1 = at(row, col - 1) + gap_penalty();
             int gap2 = at(row - 1, col) + gap_penalty();
             int score = std::min(match, std::min(gap1, gap2));
             if (local()) {
                 score = std::min(score, 0);
             }
             at(row, col) = score;
             if (score < at(row, min_score_col)) {
                 min_score_col = col;
             }
             track(row, col) = (score == match) ? MATCH :
                               (score == gap1) ? COL_INC :
                               ROW_INC;
         }
         if (max_errors() != -1 &&
                 at(row, min_score_col) > max_errors()) {
             break;
         }
         r_row = row;
         r_col = min_score_col;
     }
     if (max_errors() == -1) {
         // col -> max_col in this row
         ASSERT_TRUE(in(max_row(), max_col(max_row())));
         ASSERT_EQ(r_row, max_row());
         r_col = max_col(max_row());
         // if stopped earlier because of gap range
         int last_row = contents().first_size() - 1;
         int last_col = contents().second_size() - 1;
         if (r_row == last_row) {
             while (r_col < last_col) {
                 r_col += 1;
                 track(r_row, r_col) = COL_INC;
             }
         } else if (r_col == last_col) {
             while (r_row < last_row) {
                 r_row += 1;
                 track(r_row, r_col) = ROW_INC;
             }
         } else {
             throw Exception("row and column are not last");
         }
     }
 }
Beispiel #24
0
void execute_function(VM *vm) {
restart: {
    Frame *frame = vm->current;
    Closure *closure = frame->closure;
    Chunk *chunk = closure->chunk;
    StackObject *registers = frame->registers;

    while (frame->pc < chunk->numinstructions) {
        int instruction = chunk->instructions[frame->pc];

        OpCode o = GET_O(instruction);
        int a = GET_A(instruction);
        int b = GET_B(instruction);
        int c = GET_C(instruction);

        switch (o) {
            case OP_MOVE:
            {
                if (b < 256) {
                    copy_object(&registers[a], &registers[b]);
                } else {
                    copy_constant(vm, &registers[a], chunk->constants[b - 256]);
                }
            } break;

            case OP_GETUPVAR:
            {
                Upval *upval = closure->upvals[b];

                if (!upval->open) {
                    // upval is closed
                    copy_object(&registers[a], upval->data.o);
                } else {
                    // still on stack
                    copy_object(&registers[a], &upval->data.ref.frame->registers[upval->data.ref.slot]);
                }
            } break;

            case OP_SETUPVAR:
            {
                Upval *upval = closure->upvals[b];

                if (!upval->open) {
                    // upval is closed
                    copy_object(upval->data.o, &registers[a]);
                } else {
                    // still on stack
                    copy_object(&upval->data.ref.frame->registers[upval->data.ref.slot], &registers[a]);
                }
            } break;

            case OP_ADD:
            {
                // TODO - make string coercion better
                // TODO - make string type with special operators

                if (IS_STR(b) || IS_STR(c)) {
                    char *arg1 = TO_STR(b);
                    char *arg2 = TO_STR(c);

                    char *arg3 = malloc((strlen(arg1) + strlen(arg2) + 1) + sizeof *arg3);

                    strcpy(arg3, arg1);
                    strcat(arg3, arg2);

                    registers[a].value.o = make_string_ref(vm, arg3);
                    registers[a].type = OBJECT_REFERENCE; // put this after

                    free(arg1);
                    free(arg2);
                } else {
                    if (!(IS_INT(b) || IS_REAL(b)) || !(IS_INT(c) || IS_REAL(c))) {
                        fatal("Cannot add types.");
                    }

                    if (IS_INT(b) && IS_INT(c)) {
                        int arg1 = AS_INT(b);
                        int arg2 = AS_INT(c);

                        registers[a].type = OBJECT_INT;
                        registers[a].value.i = arg1 + arg2;
                    } else {
                        double arg1 = IS_INT(b) ? (double) AS_INT(b) : AS_REAL(b);
                        double arg2 = IS_INT(c) ? (double) AS_INT(c) : AS_REAL(c);

                        registers[a].type = OBJECT_REAL;
                        registers[a].value.d = arg1 + arg2;
                    }
                }
            } break;

            case OP_SUB:
            {
                if (!(IS_INT(b) || IS_REAL(b)) || !(IS_INT(c) || IS_REAL(c))) {
                    fatal("Tried to sub non-numbers.");
                }

                if (IS_INT(b) && IS_INT(c)) {
                    int arg1 = AS_INT(b);
                    int arg2 = AS_INT(c);

                    registers[a].type = OBJECT_INT;
                    registers[a].value.i = arg1 - arg2;
                } else {
                    double arg1 = IS_INT(b) ? (double) AS_INT(b) : AS_REAL(b);
                    double arg2 = IS_INT(c) ? (double) AS_INT(c) : AS_REAL(c);

                    registers[a].type = OBJECT_REAL;
                    registers[a].value.d = arg1 - arg2;
                }
            } break;

            case OP_MUL:
            {
                if (!(IS_INT(b) || IS_REAL(b)) || !(IS_INT(c) || IS_REAL(c))) {
                    fatal("Tried to mul non-numbers.");
                }

                if (IS_INT(b) && IS_INT(c)) {
                    int arg1 = AS_INT(b);
                    int arg2 = AS_INT(c);

                    registers[a].type = OBJECT_INT;
                    registers[a].value.i = arg1 * arg2;
                } else {
                    double arg1 = IS_INT(b) ? (double) AS_INT(b) : AS_REAL(b);
                    double arg2 = IS_INT(c) ? (double) AS_INT(c) : AS_REAL(c);

                    registers[a].type = OBJECT_REAL;
                    registers[a].value.d = arg1 * arg2;
                }
            } break;

            case OP_DIV:
            {
                if (!(IS_INT(b) || IS_REAL(b)) || !(IS_INT(c) || IS_REAL(c))) {
                    fatal("Tried to div non-numbers.");
                }

                if ((IS_INT(c) && AS_INT(c) == 0) || (IS_REAL(c) && AS_REAL(c) == 0)) {
                    fatal("Div by 0.");
                }

                if (IS_INT(b) && IS_INT(c)) {
                    int arg1 = AS_INT(b);
                    int arg2 = AS_INT(c);

                    registers[a].type = OBJECT_INT;
                    registers[a].value.i = arg1 / arg2;
                } else {
                    double arg1 = IS_INT(b) ? (double) AS_INT(b) : AS_REAL(b);
                    double arg2 = IS_INT(c) ? (double) AS_INT(c) : AS_REAL(c);

                    registers[a].type = OBJECT_REAL;
                    registers[a].value.d = arg1 / arg2;
                }
            } break;

            case OP_MOD:
            {
                if (!(IS_INT(b) || IS_REAL(b)) || !(IS_INT(c) || IS_REAL(c))) {
                    fatal("Tried to div non-numbers.");
                }

                if ((IS_INT(c) && AS_INT(c) == 0) || (IS_REAL(c) && AS_REAL(c) == 0)) {
                    fatal("Mod by 0.");
                }

                if (IS_INT(b) && IS_INT(c)) {
                    int arg1 = AS_INT(b);
                    int arg2 = AS_INT(c);

                    registers[a].type = OBJECT_INT;
                    registers[a].value.i = arg1 % arg2;
                } else {
                    double arg1 = IS_INT(b) ? (double) AS_INT(b) : AS_REAL(b);
                    double arg2 = IS_INT(c) ? (double) AS_INT(c) : AS_REAL(c);

                    registers[a].type = OBJECT_REAL;
                    registers[a].value.i = fmod(arg1, arg2);
                }
            } break;

            case OP_POW:
            {
                if (!(IS_INT(b) || IS_REAL(b)) || !(IS_INT(c) || IS_REAL(c))) {
                    fatal("Tried to div non-numbers.");
                }

                if (IS_INT(b) && IS_INT(c)) {
                    int arg1 = AS_INT(b);
                    int arg2 = AS_INT(c);

                    registers[a].type = OBJECT_INT;
                    registers[a].value.i = (int) pow(arg1, arg2);
                } else {
                    double arg1 = IS_INT(b) ? (double) AS_INT(b) : AS_REAL(b);
                    double arg2 = IS_INT(c) ? (double) AS_INT(c) : AS_REAL(c);

                    registers[a].type = OBJECT_REAL;
                    registers[a].value.d = pow(arg1, arg2);
                }
            } break;

            case OP_NEG:
            {
                if (IS_INT(b)) {
                    registers[a].type = OBJECT_INT;
                    registers[a].value.i = -AS_INT(b);
                } else if (IS_REAL(b)) {
                    registers[a].type = OBJECT_INT;
                    registers[a].value.i = -AS_REAL(b);
                } else {
                    fatal("Tried to negate non-numeric type.");
                }
            } break;

            case OP_NOT:
            {
                if (registers[a].type != OBJECT_BOOL) {
                    fatal("Expected boolean type, not %d.", registers[a].type);
                }

                registers[a].value.i = registers[a].value.i == 1 ? 0 : 1;
            } break;

            case OP_EQ:
            {
                if ((IS_INT(b) || IS_REAL(b)) && (IS_INT(c) || IS_REAL(c))) {
                    double arg1 = IS_INT(b) ? (double) AS_INT(b) : AS_REAL(b);
                    double arg2 = IS_INT(c) ? (double) AS_INT(c) : AS_REAL(c);

                    registers[a].type = OBJECT_BOOL;
                    registers[a].value.i = arg1 == arg2;
                } else {
                    fatal("Comparison of reference types not yet supported.");
                }
            } break;

            case OP_LT:
            {
                if (!(IS_INT(b) || IS_REAL(b)) || !(IS_INT(c) || IS_REAL(c))) {
                    fatal("Tried to compare non-numbers.");
                }

                double arg1 = IS_INT(b) ? (double) AS_INT(b) : AS_REAL(b);
                double arg2 = IS_INT(c) ? (double) AS_INT(c) : AS_REAL(c);

                registers[a].type = OBJECT_BOOL;
                registers[a].value.i = arg1 < arg2;
            } break;

            case OP_LE:
            {
                if (!(IS_INT(b) || IS_REAL(b)) || !(IS_INT(c) || IS_REAL(c))) {
                    fatal("Tried to compare non-numbers.");
                }

                double arg1 = IS_INT(b) ? (double) AS_INT(b) : AS_REAL(b);
                double arg2 = IS_INT(c) ? (double) AS_INT(c) : AS_REAL(c);

                registers[a].type = OBJECT_BOOL;
                registers[a].value.i = arg1 <= arg2;
            } break;

            case OP_CLOSURE:
            {
                Closure *child = make_closure(chunk->children[b]);

                int i;
                for (i = 0; i < chunk->children[b]->numupvars; i++) {
                    int inst = chunk->instructions[++frame->pc];

                    OpCode oc = GET_O(inst);
                    int ac = GET_A(inst);
                    int bc = GET_B(inst);
                    int cc = GET_C(inst);

                    if (oc == OP_MOVE) {
                        // first upval for this variable
                        child->upvals[ac] = make_upval(vm, bc);
                    } else {
                        // share upval
                        child->upvals[ac] = closure->upvals[bc];
                        child->upvals[ac]->refcount++;
                    }
                }

                registers[a].value.o = make_closure_ref(vm, child);
                registers[a].type = OBJECT_REFERENCE; // put this after
            } break;

            case OP_CALL:
            {
                if (registers[b].type != OBJECT_REFERENCE || registers[b].value.o->type != OBJECT_CLOSURE) {
                    fatal("Tried to call non-closure.");
                }

                // TODO - safety issue (see compile.c for notes)

                Closure *child = registers[b].value.o->value.c;
                Frame *subframe = make_frame(frame, child);

                int i;
                for (i = 0; i < child->chunk->numparams; i++) {
                    copy_object(&subframe->registers[i + 1], &registers[c + i]);
                }

                vm->current = subframe;
                goto restart;
            } break;

            case OP_RETURN:
            {
                UpvalNode *head;
                for (head = vm->open; head != NULL; ) {
                    Upval *u = head->upval;

                    if (u->data.ref.frame == frame) {
                        StackObject *o = malloc(sizeof *o);

                        if (!o) {
                            fatal("Out of memory.");
                        }

                        u->open = 0;
                        copy_object(o, &registers[u->data.ref.slot]);
                        u->data.o = o;

                        if (vm->open == head) {
                            vm->open = head->next;
                        } else {
                            head->next->prev = head->prev;
                            head->prev->next = head->next;
                        }

                        UpvalNode *temp = head;
                        head = head->next;
                        free(temp);
                    } else {
                        head = head->next;
                    }
                }

                if (vm->current->parent != NULL) {
                    Frame *p = vm->current->parent;
                    StackObject *target = &p->registers[GET_A(p->closure->chunk->instructions[p->pc++])];

                    if (b < 256) {
                        // debug
                        char *d = obj_to_str(&registers[b]);
                        printf("Return value: %s\n", d);
                        free(d);

                        copy_object(target, &registers[b]);
                    } else {
                        copy_constant(vm, target, chunk->constants[b - 256]);
                    }

                    free_frame(frame);

                    vm->current = p;
                    goto restart;
                } else {
                    // debug
                    char *d = obj_to_str(&registers[b]);
                    printf("Return value: %s\n", d);
                    free(d);

                    free_frame(frame);
                    vm->current = NULL;
                    return;
                }
            } break;

            case OP_JUMP:
                frame->pc += c ? -b : b;
                break;

            case OP_JUMP_TRUE:
            {
                if (registers[a].type != OBJECT_BOOL) {
                    fatal("Expected boolean type, not %d.", registers[a].type);
                }

                if (registers[a].value.i == 1) {
                    frame->pc += c ? -b : b;
                }
            } break;

            case OP_JUMP_FALSE:
            {
                if (registers[a].type != OBJECT_BOOL) {
                    fatal("Expected boolean type, not %d.", registers[a].type);
                }

                if (registers[a].value.i == 0) {
                    frame->pc += c ? -b : b;
                }
            } break;

            case OP_ENTER_TRY:
            {
                vm->catchframe = make_catch_frame(frame, vm->catchframe, frame->pc + b);
            } break;

            case OP_LEAVE_TRY:
            {
                CatchFrame *temp = vm->catchframe;
                vm->catchframe = vm->catchframe->parent;
                free_catch_frame(temp);
            } break;

            case OP_THROW:
            {
                // TODO - replace unwinding of stack with an exceptions
                // table per-chunk. It will have an instructions range,
                // the starting instruction of a handler, and the type of
                // exception that it may handle.

                // Exception table:
                // From    To      Target      Type
                // 0       4       5           Class TestExc1
                // 0       12      12          Class TestExc2

                // TODO - implement a way to expect an exception
                // of a given type instead of a generic catch-all.

                char *s = obj_to_str(&registers[a]);
                printf("Exception value: %s!\n", s);
                free(s);

                // TODO - this is probably wrong. Not sure how complicated
                // it will be to handle upvalues and frame destruction here,
                // so we're just doing it a shitty way for now :D [GO LAZE].

                if (!vm->catchframe) {
                    // TODO - print a stack trace [ requires debug symbols :( ]
                    fatal("Exception thrown outside of handler.");
                }

                while (vm->current != vm->catchframe->frame) {
                    // TODO - destruct frame
                    vm->current = vm->current->parent;
                }

                vm->current->pc = vm->catchframe->target;

                CatchFrame *temp = vm->catchframe;
                vm->catchframe = vm->catchframe->parent;
                free_catch_frame(temp);

                goto restart;
            } break;
        }

        frame->pc++;
    }

    fatal("VM left instruction-space.");
}
}
Beispiel #25
0
frame_ptr make_frame(widget_ptr w, const std::string& name) {
	key_mapper_ptr keys(new key_mapper());
	return make_frame(w, name, keys);
}