Пример #1
0
void test_ui_sdl_grath()
{
    Sdl_Graph *sdl_grath;
	allocator_t *allocator = allocator_get_default_alloc();
    char *set_str;
    cjson_t *root, *e, *s;
    char buf[2048];

    root = cjson_create_object();{
        cjson_add_item_to_object(root, "Sdl_Graph", e = cjson_create_object());{
            cjson_add_string_to_object(e, "name", "alan");
        }
    }

    set_str = cjson_print(root);

    sdl_grath = OBJECT_NEW(allocator, Sdl_Graph,set_str);

    object_dump(sdl_grath, "Sdl_Graph", buf, 2048);
    dbg_str(DBG_DETAIL,"Sdl_Graph dump: %s",buf);

    object_destroy(sdl_grath);

    free(set_str);

}
Пример #2
0
void test_obj_event()
{
	Event *event;
	allocator_t *allocator = allocator_get_default_alloc();

    event = OBJECT_NEW(allocator, Event,"");
}
Пример #3
0
static void * __render_load_text(Sdl_Graph *graph,void *string,void *font,int r, int g, int b, int a)
{
	allocator_t *allocator = ((Obj *)graph)->allocator;
	Sdl_Text *text;
	Sdl_Font *f = (Sdl_Font *)font;
	SDL_Surface* surface = NULL;
	SDL_Color textColor = {r, g, b, a };
	String *content;

	dbg_str(DBG_DETAIL,"Sdl_Text load text");
    text = OBJECT_NEW(allocator, Sdl_Text,"");
	content = ((Text *)text)->content;
	content->assign(content,string);

	surface = TTF_RenderText_Solid(f->ttf_font,
                                   ((Text *)text)->content->value,
                                   textColor ); 

	if(surface != NULL) {
		text->texture = SDL_CreateTextureFromSurface(graph->render, surface);
		text->width = surface->w;
		text->height = surface->h;
		dbg_str(DBG_DETAIL,"width =%d height=%d",text->width, text->height);
		SDL_FreeSurface(surface);
	}

	return text;
}
Пример #4
0
static void * __render_load_character(Sdl_Graph *graph,uint32_t code,void *font,int r, int g, int b, int a)
{
	allocator_t *allocator = ((Obj *)graph)->allocator;
	Character *character;
	Sdl_Font *f = (Sdl_Font *)font;
	SDL_Surface* surface = NULL;
	SDL_Color character_color = {r, g, b, a };
	char buf[10] = {0};

	/*
	 *dbg_str(DBG_DETAIL,"Sdl_Character load character");
	 */
    character = OBJECT_NEW(allocator, Sdl_Character,"");
	character->assign(character,code);

	sprintf(buf,"%c",code);

	surface = TTF_RenderText_Solid(f->ttf_font,
                                   buf,
                                   character_color); 

	if(surface != NULL) {
		((Sdl_Character *)character)->texture = SDL_CreateTextureFromSurface(graph->render, surface);
		character->width   = surface->w;
		character->height  = surface->h;
		/*
		 *dbg_str(DBG_DETAIL,"width =%d height=%d",character->width, character->height);
		 */
		SDL_FreeSurface(surface);
	}

	return character;
}
Пример #5
0
static void *__create_event(Window *window)
{
	allocator_t *allocator = ((Obj *)window)->allocator;

    dbg_str(DBG_DETAIL,"sdl window create_event");

    window->event = OBJECT_NEW(allocator, Sdl_Event,"");
}
Пример #6
0
static void *__create_graph(Window *window, char *graph_type)
{
	allocator_t *allocator = ((Obj *)window)->allocator;

    dbg_str(DBG_DETAIL,"sdl window create_graph");

	window->graph = (Graph *)OBJECT_NEW(allocator, Sdl_Graph,NULL);
}
Пример #7
0
static void *__create_font(Window *window,char *font_name)
{
	allocator_t *allocator = ((Obj *)window)->allocator;

    dbg_str(DBG_DETAIL,"sdl window create_font");

    window->font = OBJECT_NEW(allocator, Sdl_Font,"");
	window->font->load_font(window->font);
}
Пример #8
0
/* Encode an object, returning the data. */
uint32_t
encode_object(uint32_t data, uint32_t devnum)
{
	uint32_t retval;
	uint8_t otype;

	otype = DATA_TYPE_DEV(devnum);
	retval = (otype == TYPE_NONE) ? swap32(data) : OBJECT_NEW(otype, data);
	return (retval);
}
Пример #9
0
void test_obj_sdl_font()
{
	Font *font;
	allocator_t *allocator = allocator_get_default_alloc();
	int w, h;

    font = OBJECT_NEW(allocator, Sdl_Font,"");
	w = font->get_character_width(font,'a');
	h = font->get_character_height(font,'a');

	dbg_str(DBG_DETAIL,"a's w=%d h=%d", w, h);

}
Пример #10
0
void test_ui_button()
{
    Subject *subject;
	allocator_t *allocator = allocator_get_default_alloc();
    char *set_str;
    char buf[2048];

    set_str = gen_button_setting_str();

    subject = OBJECT_NEW(allocator, Button,set_str);

    object_dump(subject, "Button", buf, 2048);
    dbg_str(DBG_DETAIL,"Button dump: %s",buf);

    free(set_str);

}
Пример #11
0
void test_ui_component()
{
    Subject *subject;
	allocator_t *allocator = allocator_get_default_alloc();
    char *set_str;
    cjson_t *root, *e, *s;
    char buf[2048];

    root = cjson_create_object();{
        cjson_add_item_to_object(root, "Component", e = cjson_create_object());{
            cjson_add_item_to_object(e, "Subject", s = cjson_create_object());{
                cjson_add_number_to_object(s, "x", 1);
                cjson_add_number_to_object(s, "y", 25);
                cjson_add_number_to_object(s, "width", 5);
                cjson_add_number_to_object(s, "height", 125);
            }
            cjson_add_string_to_object(e, "name", "alan");
        }
    }

    set_str = cjson_print(root);

    /*
     *subject = OBJECT_ALLOC(allocator,Component);
     *object_set(subject, "Component", set_str);
     *dbg_str(DBG_DETAIL,"x=%d y=%d width=%d height=%d",subject->x,subject->y,subject->width,subject->height);
     */

    subject = OBJECT_NEW(allocator, Component,set_str);

    /*
     *dbg_str(DBG_DETAIL,"x=%d y=%d width=%d height=%d",subject->x,subject->y,subject->width,subject->height);
     *dbg_str(DBG_DETAIL,"component nane=%s",((Component *)subject)->name);
     *subject->move(subject);
     */

    object_dump(subject, "Component", buf, 2048);
    dbg_str(DBG_DETAIL,"Component dump: %s",buf);

    free(set_str);

}
Пример #12
0
void test_ui_sdl_window()
{
    Window *window;
	Graph *g;
	allocator_t *allocator = allocator_get_default_alloc();
    char *set_str;
    char buf[2048];

    set_str = gen_window_setting_str();

    window  = OBJECT_NEW(allocator, Sdl_Window,set_str);
	g       = window->graph;

    object_dump(window, "Sdl_Window", buf, 2048);
    dbg_str(DBG_DETAIL,"Window dump: %s",buf);

	dbg_str(DBG_DETAIL,"render draw test");
	g->render_draw_image(g,0,0,window->background);
	g->render_present(g);

    sleep(2);
	g->render_clear(g);
	g->render_set_color(g,0xff,0x0,0xff,0xff);
	g->render_draw_line(g,20,0,50,50);
	g->render_set_color(g,0xff,0x0,0x0,0xff);
	g->render_draw_rect(g,20,20,100,100);
	/*
	 *g->render_fill_rect(g,20,20,100,100);
	 */
	g->render_present(g);
	sleep(5);

    object_destroy(window);

    free(set_str);

}
Пример #13
0
static void *__render_load_image(Sdl_Graph *graph,void *path)
{

	Sdl_Image *image;
	allocator_t *allocator = ((Obj *)graph)->allocator;

	dbg_str(DBG_DETAIL,"SDL Graph render_load_image");

    image = OBJECT_NEW(allocator, Sdl_Image,"");
	((Image *)image)->path->assign(((Image *)image)->path,path);
	if(image->surface == NULL) {
		image->load_image((Image *)image);
	}

	if(image->surface != NULL) {
		image->texture = SDL_CreateTextureFromSurface(graph->render, image->surface);
		image->width   = image->surface->w;
		image->height  = image->surface->h;
		SDL_FreeSurface(image->surface);
        image->surface = NULL;
	}

	return image;
}
Пример #14
0
void test_obj_map()
{
    Map *map;
	allocator_t *allocator = allocator_get_default_alloc();
    char *set_str;
    cjson_t *root, *e, *s;
    char buf[2048];

    root = cjson_create_object();{
        cjson_add_item_to_object(root, "Map", e = cjson_create_object());{
            cjson_add_string_to_object(e, "name", "alan");
        }
    }

    set_str = cjson_print(root);

    map = OBJECT_NEW(allocator, Map,set_str);

    object_dump(map, "Map", buf, 2048);
    dbg_str(OBJ_DETAIL,"Map dump: %s",buf);

    free(set_str);

}
Пример #15
0
/*
 * Create runtime and compilation environment and set up it
 * according to arguments. Executes 'core.yoyo' from standart library
 * to set up minimal runtime environment and file specified in arguments.
 * */
int main(int argc, char** argv) {
	setlocale(LC_ALL, "");
	signal(SIGSEGV, Signal_handler);
	signal(SIGFPE, Signal_handler);

	YoyoCEnvironment* ycenv = newYoyoCEnvironment(NULL);
	Environment* env = (Environment*) ycenv;
	YDebug* debug = NULL;
	bool dbg = false;

	env->argv = NULL;
	env->argc = 0;
	wchar_t* file = NULL;

	for (size_t i = 1; i < argc; i++) {
		char* arg = argv[i];
		if (arg[0] == '-' && strlen(arg) > 1) {
			arg++;
			if (arg[0] == '-') {
				/* Arguments like --... (e.g. --debug) */
				arg++;
				if (strcmp(arg, "debug") == 0)
					dbg = true;
				else if (strcmp(arg, "help") == 0) {
					printf("Yoyo v"VERSION" - tiny dynamic language.\n"
								"View code examples in repository\n"
								"Use:\n\tyoyo [OPTIONS] FILE arg1 arg2 ...\n"
								"Options:\n"
								"\t--debug - execute in debug mode\n"
								"\t--help - display brief help\n"
								"\t--version - display project version\n"
								"\t-Ppath - add path to file search path\n"
								"\t-Dkey=value - define key\n"
								"Most useful keys:\n"
								"\tystd - specify standart library location\n"
								"\tobjects = hash/tree - specify used object implementation\n"
								"\tIntPool - specify integer pool size(Strongly affects on memory use and performance)\n"
								"\tIntCache - specify integer cache size(Strongly affects on memory use and performance)\n"
								"\tworkdir - specify working directory\n"
								"\nAuthor: Eugene Protopopov <*****@*****.**>\n"
								"License: Program, standart library and examples are distributed under the terms of GNU GPLv3 or any later version.\n"
								"Program repo: https://github.com/protopopov1122/Yoyo");
					exit(0);
				}
				else if (strcmp(arg, "version") == 0) {
					printf("v"VERSION"\n");
					exit(0);
				}
			} else if (arg[0] == 'D') {
				/* Environment variable definitions.
				 * Format: -Dkey=value */
				arg++;
				char* key = NULL;
				char* value = NULL;
				size_t key_len = 0;
				size_t value_len = 0;
				while (*arg != '=' && *arg != '\0') {
					key = realloc(key, sizeof(char) * (++key_len));
					key[key_len - 1] = *(arg++);
				}
				key = realloc(key, sizeof(char) * (++key_len));
				key[key_len - 1] = '\0';
				while (*arg != '\0') {
					arg++;
					value = realloc(value, sizeof(char) * (++value_len));
					value[value_len - 1] = *arg;
				}
				wchar_t* wkey = calloc(1, sizeof(wchar_t) * (strlen(key) + 1));
				wchar_t* wvalue = calloc(1,
						sizeof(wchar_t)
								* (strlen(value != NULL ? value : "none") + 1));
				mbstowcs(wkey, key, strlen(key));
				mbstowcs(wvalue, value != NULL ? value : "none",
						strlen(value != NULL ? value : "none"));
				env->define(env, wkey, wvalue);
				free(wkey);
				free(wvalue);
				free(key);
				free(value);
			} else if (arg[0] == 'P') {
				/*Runtime path definitions.
				 * Format: -Ppath*/
				arg++;
				wchar_t* wpath = malloc(sizeof(wchar_t) * (strlen(arg) + 1));
				mbstowcs(wpath, arg, strlen(arg));
				wpath[strlen(arg)] = L'\0';
				env->addPath(env, wpath);
				free(wpath);
			}
		} else {
			/* If file to execute is not defined, then current
			 * argument is file. Else it is an argument to
			 * yoyo program. */
			if (file == NULL) {
				file = malloc(sizeof(wchar_t) * (strlen(arg) + 1));
				mbstowcs(file, arg, strlen(arg));
				file[strlen(arg)] = L'\0';
			} else {
				wchar_t* warg = malloc(sizeof(wchar_t) * (strlen(arg) + 1));
				mbstowcs(warg, arg, strlen(arg));
				warg[strlen(arg)] = L'\0';
				env->argc++;
				env->argv = realloc(env->argv, sizeof(wchar_t*) * env->argc);
				env->argv[env->argc - 1] = warg;
			}
		}
	}
	/* Adds minimal path: working directory(by default is '.') and
	 * standart library directory(by default is working directory). */
	wchar_t* workdir = env->getDefined(env, L"workdir");
	wchar_t* libdir = env->getDefined(env, L"ystd");
	workdir = workdir == NULL ? L"." : workdir;
	char* mbs_wd = calloc(1, sizeof(wchar_t) * (wcslen(workdir) + 1));
	wcstombs(mbs_wd, workdir, sizeof(wchar_t) * wcslen(workdir));
	chdir(mbs_wd);
	free(mbs_wd);
	env->addPath(env, workdir);
	env->addPath(env, libdir == NULL ? YSTD_PATH : libdir);
	if (env->getDefined(env, L"objects")==NULL)
		env->define(env, L"objects", OBJ_TYPE);
#ifdef GCGenerational
	if (env->getDefined(env, L"GCPlain")==NULL)
		env->define(env, L"GCGenerational", L"");
#endif

	JitCompiler* jit = NULL;
	if (env->getDefined(env, L"yjit")!=NULL) {
		wchar_t* wcs = env->getDefined(env, L"yjit");
		char* mbs = calloc(1, sizeof(wchar_t)*(wcslen(wcs)+1));
		wcstombs(mbs, wcs, sizeof(wchar_t) * wcslen(wcs));
		void* handle = dlopen(mbs, RTLD_NOW);
		if (handle!=NULL) {
			void* ptr = dlsym(handle, "getYoyoJit");
			if (ptr!=NULL) {
				JitGetter* getter_ptr = (JitGetter*) &ptr;
				JitGetter getter = *getter_ptr;
				jit = getter();
			}
			else
				fprintf(env->err_stream, "%s\n", dlerror());
		}
		else
			fprintf(env->err_stream, "%s\n", dlerror());
		free(mbs);
	}

	YRuntime* runtime = newRuntime(env, NULL);
	ycenv->bytecode = newBytecode(&runtime->symbols);
	ycenv->preprocess_bytecode = true;
	bool dumpcode = env->getDefined(env, L"dumpcode");
	ycenv->analyze_bytecode = dumpcode || jit != NULL;

	if (dbg)
		debug = newDefaultDebugger(ycenv->bytecode);

	OBJECT_NEW(runtime->global_scope, L"sys",
			Yoyo_SystemObject(ycenv->bytecode, yoyo_thread(runtime)),
			yoyo_thread(runtime));

	int32_t pid = -1;
	bool exectime = env->getDefined(env, L"exectime") != NULL;
	/* Executes specified file only if 'core.yoyo' is found and valid */
	if (Yoyo_interpret_file(ycenv->bytecode, runtime, L"core.yoyo") != -1) {
		runtime->debugger = debug;
		if (file != NULL) {
			clock_t start = clock();
			pid = Yoyo_interpret_file(ycenv->bytecode, runtime, file);
			if (exectime)
				printf("Execution time: %lf\n", (double) (clock() - start) / CLOCKS_PER_SEC);
			free(file);
		} else {
			Yoyo_interpret_file(ycenv->bytecode, runtime, L"repl.yoyo");
		}
	}

	if (dumpcode) {
		for (size_t i = 0; i < ycenv->bytecode->procedure_count; i++) {
			if (ycenv->bytecode->procedures[i] == NULL)
				continue;
			ProcedureStats* stats = ycenv->bytecode->procedures[i]->stats;
			if (stats != NULL)
				print_stats(stats);
		}
	}
	if (env->getDefined(env, L"testjit") != NULL) {
		if (pid != -1 && jit != NULL) {
			ycenv->bytecode->procedures[pid]->compiled = jit->compile(jit,
				ycenv->bytecode->procedures[pid], ycenv->bytecode);
			clock_t start = clock();
			invoke(pid, ycenv->bytecode, runtime->global_scope, NULL, yoyo_thread(runtime));
			if (exectime)
				printf("Execution time: %lf\n", (double) (clock() - start) / CLOCKS_PER_SEC);
		}	
	}

	/* Waits all threads to finish and frees resources */
	YThread* current_th = yoyo_thread(runtime);
	current_th->free(current_th);
	runtime->wait(runtime);
	runtime->free(runtime);
	if (debug != NULL)
		debug->free(debug);
	if (jit!=NULL)
		jit->free(jit);

	exit(EXIT_SUCCESS);
}
Пример #16
0
/*Procedure that interprets current frame bytecode
 * Uses loop with switch statement.*/
YValue* EXECUTE_PROC(YObject* scope, YThread* th) {
	ExecutionFrame* frame = (ExecutionFrame*) th->frame;
	frame->regs[0] = (YValue*) scope;
	YRuntime* runtime = th->runtime;
	ILBytecode* bc = frame->bytecode;
	size_t code_len = frame->proc->code_length;

	while (frame->pc + 13 <= code_len) {
		// If runtime is paused then execution should be paused too.
		if (runtime->state == RuntimePaused) {
			th->state = ThreadPaused;
			while (runtime->state == RuntimePaused)
				YIELD();
			th->state = ThreadWorking;
		}
		// Decode opcode and arguments
		uint8_t opcode = frame->proc->code[frame->pc];

		int32_t* args = (int32_t*) &(frame->proc->code[frame->pc + 1]);
		const int32_t iarg0 = args[0];
		const int32_t iarg1 = args[1];
		const int32_t iarg2 = args[2];

		// Call debugger before each instruction if nescesarry
		YBreakpoint breakpoint = { .procid = frame->proc->id, .pc = frame->pc };
		DEBUG(th->runtime->debugger, instruction, &breakpoint, th);

		// Interpret opcode
		// See virtual machine description
		switch (opcode) {
		case VM_Halt:
			break;
		case VM_LoadConstant: {
			/*All constants during execution should be stored in pool.
			 * If pool contains constant id, then constant is returned*/
			YObject* cpool = th->runtime->Constants.pool;
			if (cpool->contains(cpool, iarg1, th)) {
				SET_REGISTER(cpool->get(cpool, iarg1, th), iarg0, th);
				break;
			}
			/*Else it is created, added to pool and returned*/
			Constant* cnst = bc->getConstant(bc, iarg1);
			YValue* val = getNull(th);
			if (cnst != NULL) {
				switch (cnst->type) {
				case IntegerC:
					val = newInteger(cnst->value.i64, th);
					break;
				case FloatC:
					val = newFloat(cnst->value.fp64, th);
					break;
				case StringC:
					val = newString(
							bc->getSymbolById(bc,
									cnst->value.string_id), th);
					break;
				case BooleanC:
					val = newBoolean(cnst->value.boolean, th);
					break;
				default:
					break;
				}
			}
			cpool->put(cpool, iarg1, val, true, th);
			SET_REGISTER(val, iarg0, th);
		}
			break;
		case VM_LoadInteger: {
			/*Load integer from argument directly to register*/
			YValue* val = newInteger(iarg1, th);
			SET_REGISTER(val, iarg0, th);
		}
			break;
		case VM_Copy: {
			/*Copy register value to another*/
			SET_REGISTER(getRegister(iarg1, th), iarg0, th);
		}
			break;
		case VM_Push: {
			/*Push register value to stack*/
			push(getRegister(iarg0, th), th);
		}
			break;
		case VM_PushInteger: {
			push(newInteger(iarg0, th), th);
		}
		break;

			/*Next instructions load values from two registers,
			 * perform polymorph binary operation and
			 * save result to third register*/
		case VM_Add: {
			YValue* v1 = getRegister(iarg1, th);
			YValue* v2 = getRegister(iarg2, th);
			SET_REGISTER(v1->type->oper.add_operation(v1, v2, th), iarg0, th);
		}
			break;
		case VM_Subtract: {
			YValue* v1 = getRegister(iarg1, th);
			YValue* v2 = getRegister(iarg2, th);
			SET_REGISTER(v1->type->oper.subtract_operation(v1, v2, th), iarg0,
					th);
		}
			break;
		case VM_Multiply: {
			YValue* v1 = getRegister(iarg1, th);
			YValue* v2 = getRegister(iarg2, th);
			SET_REGISTER(v1->type->oper.multiply_operation(v1, v2, th), iarg0,
					th);
		}
			break;
		case VM_Divide: {
			YValue* v1 = getRegister(iarg1, th);
			YValue* v2 = getRegister(iarg2, th);
			SET_REGISTER(v1->type->oper.divide_operation(v1, v2, th), iarg0, th);
		}
			break;
		case VM_Modulo: {
			YValue* v1 = getRegister(iarg1, th);
			YValue* v2 = getRegister(iarg2, th);
			SET_REGISTER(v1->type->oper.modulo_operation(v1, v2, th), iarg0, th);
		}
			break;
		case VM_Power: {
			YValue* v1 = getRegister(iarg1, th);
			YValue* v2 = getRegister(iarg2, th);
			SET_REGISTER(v1->type->oper.power_operation(v1, v2, th), iarg0, th);
		}
			break;
		case VM_ShiftRight: {
			YValue* v1 = getRegister(iarg1, th);
			YValue* v2 = getRegister(iarg2, th);
			SET_REGISTER(v1->type->oper.shr_operation(v1, v2, th), iarg0, th);
		}
			break;
		case VM_ShiftLeft: {
			YValue* v1 = getRegister(iarg1, th);
			YValue* v2 = getRegister(iarg2, th);
			SET_REGISTER(v1->type->oper.shl_operation(v1, v2, th), iarg0, th);
		}
			break;
		case VM_And: {
			YValue* v1 = getRegister(iarg1, th);
			YValue* v2 = getRegister(iarg2, th);
			SET_REGISTER(v1->type->oper.and_operation(v1, v2, th), iarg0, th);
		}
			break;
		case VM_Or: {
			YValue* v1 = getRegister(iarg1, th);
			YValue* v2 = getRegister(iarg2, th);
			SET_REGISTER(v1->type->oper.or_operation(v1, v2, th), iarg0, th);
		}
			break;
		case VM_Xor: {
			YValue* v1 = getRegister(iarg1, th);
			YValue* v2 = getRegister(iarg2, th);
			SET_REGISTER(v1->type->oper.xor_operation(v1, v2, th), iarg0, th);
		}
			break;
		case VM_Compare: {
			YValue* v1 = getRegister(iarg1, th);
			YValue* v2 = getRegister(iarg2, th);

			SET_REGISTER(newInteger(v1->type->oper.compare(v1, v2, th), th),
					iarg0, th);
		}
			break;

		case VM_Test: {
			/*Take an integer from register and
			 * check if certain bit is 1 or 0*/
			YValue* arg = getRegister(iarg1, th);
			if (arg->type == &th->runtime->IntType) {
				int64_t i = ((YInteger*) arg)->value;
				YValue* res = newBoolean((i & iarg2) != 0, th);
				SET_REGISTER(res, iarg0, th);
			} else
				SET_REGISTER(getNull(th), iarg0, th);
		}
			break;
		case VM_FastCompare: {
			YValue* v1 = getRegister(iarg0, th);
			YValue* v2 = getRegister(iarg1, th);
			int i = v1->type->oper.compare(v1, v2, th);
			YValue* res = newBoolean((i & iarg2) != 0, th);
			SET_REGISTER(res, iarg0, th);
		}
		break;
			/*These instruction perform polymorph unary operations*/
		case VM_Negate: {
			YValue* v1 = getRegister(iarg1, th);
			SET_REGISTER(v1->type->oper.negate_operation(v1, th), iarg0, th);
		}
			break;
		case VM_Not: {
			YValue* v1 = getRegister(iarg1, th);
			SET_REGISTER(v1->type->oper.not_operation(v1, th), iarg0, th);
		}
			break;
		case VM_Increment: {
			YValue* v1 = getRegister(iarg1, th);
			if (v1->type == &th->runtime->IntType) {
				int64_t i = getInteger(v1, th);
				i++;
				SET_REGISTER(newInteger(i, th), iarg0, th);
			} else if (v1->type==&th->runtime->FloatType) {
				double i = getFloat(v1, th);
				i++;
				SET_REGISTER(newFloat(i, th), iarg0, th);
			} else {
				SET_REGISTER(v1, iarg0, th);
			}

		}
		break;
		case VM_Decrement: {
			YValue* v1 = getRegister(iarg1, th);
			if (v1->type == &th->runtime->IntType) {
				int64_t i = getInteger(v1, th);
				i--;
				SET_REGISTER(newInteger(i, th), iarg0, th);
			} else if (v1->type==&th->runtime->FloatType) {
				double i = getFloat(v1, th);
				i--;
				SET_REGISTER(newFloat(i, th), iarg0, th);
			} else {
				SET_REGISTER(v1, iarg0, th);
			}

		}
		break;

		case VM_Call: {
			/*Invoke lambda from register.
			 * Arguments stored in stack.
			 * Argument count passed as argument*/
			size_t argc = (size_t) popInt(th);
/*			YValue** args = malloc(sizeof(YValue*) * argc);
			for (size_t i = argc - 1; i < argc; i--)
				args[i] = pop(th);*/
			YValue** args = &((ExecutionFrame*) th->frame)->stack[((ExecutionFrame*) th->frame)->stack_offset] - argc;
			((ExecutionFrame*) th->frame)->stack_offset -= argc;
			YValue* val = getRegister(iarg1, th);
			YObject* scope = NULL;
			if (iarg2 != -1) {
				YValue* scl = getRegister(iarg2, th);
				if (scl->type == &th->runtime->ObjectType)
					scope = (YObject*) scl;
				else {
					scope = th->runtime->newObject(NULL, th);
					OBJECT_NEW(scope, L"value", scl, th);
				}
			}
			if (val->type == &th->runtime->LambdaType) {

				YLambda* l = (YLambda*) val;
				SET_REGISTER(invokeLambda(l, scope, args, argc, th), iarg0, th);
			} else {
				throwException(L"CallingNotALambda", NULL, 0, th);
				SET_REGISTER(getNull(th), iarg0, th);
			}
			//free(args);
		}
			break;
		case VM_Return: {
			/*Verify register value to be some type(if defined)
			 * and return it. Execution has been ended*/
			YValue* ret = getRegister(iarg0, th);
			if (((ExecutionFrame*) th->frame)->retType != NULL
					&& !((ExecutionFrame*) th->frame)->retType->verify(
							((ExecutionFrame*) th->frame)->retType, ret, th)) {
				wchar_t* wstr = toString(ret, th);
				throwException(L"Wrong return type", &wstr, 1, th);
				free(wstr);
				return getNull(th);
			}
			return ret;
		}
		case VM_NewObject: {
			/*Create object with parent(if defined)*/
			YValue* p = getRegister(iarg1, th);
			if (iarg1 != -1 && p->type == &th->runtime->ObjectType) {
				YObject* obj = th->runtime->newObject((YObject*) p, th);
				SET_REGISTER((YValue*) obj, iarg0, th);
			} else
				SET_REGISTER((YValue*) th->runtime->newObject(NULL, th), iarg0,
						th);
		}
			break;
		case VM_NewArray: {
			/*Create empty array*/
			SET_REGISTER((YValue*) newArray(th), iarg0, th);
		}
			break;
		case VM_NewLambda: {
			/*Create lambda. Lambda signature is stored in stack.
			 * It is popped and formed as signature*/
			// Check if lambda is vararg
			YValue* vmeth = pop(th);
			bool meth =
					(vmeth->type == &th->runtime->BooleanType) ?
							((YBoolean*) vmeth)->value : false;
			YValue* vvararg = pop(th);
			bool vararg =
					(vvararg->type == &th->runtime->BooleanType) ?
							((YBoolean*) vvararg)->value : false;
			// Get argument count and types
			size_t argc = (size_t) popInt(th);
			int32_t* argids = calloc(1, sizeof(int32_t) * argc);
			YoyoType** argTypes = calloc(1, sizeof(YoyoType*) * argc);
			for (size_t i = argc - 1; i < argc; i--) {
				argids[i] = (int32_t) popInt(th);
				YValue* val = pop(th);
				if (val->type == &th->runtime->DeclarationType)
					argTypes[i] = (YoyoType*) val;
				else
					argTypes[i] = val->type->TypeConstant;
			}
			// Get lambda return type
			YValue* retV = pop(th);
			YoyoType* retType = NULL;
			if (retV->type == &th->runtime->DeclarationType)
				retType = (YoyoType*) retV;
			else
				retType = retV->type->TypeConstant;
			// Get lambda scope from argument and create
			// lambda signature and lambda
			YValue* sp = getRegister(iarg2, th);
			if (sp->type == &th->runtime->ObjectType) {
				YObject* scope = (YObject*) sp;
				YLambda* lmbd = newProcedureLambda(iarg1, bc, scope, argids,
						newLambdaSignature(meth, argc, vararg, argTypes,
								retType, th), th);
				SET_REGISTER((YValue*) lmbd, iarg0, th);
			} else
				SET_REGISTER(getNull(th), iarg0, th);
			// Free allocated resources
			free(argids);
			free(argTypes);
		}
			break;
		case VM_NewOverload: {
			/*Pop lambdas from stack and
			 * create overloaded lambda*/
			// Pop lambda count and lambdas
			size_t count = (size_t) iarg1;
			YLambda** lambdas = malloc(sizeof(YLambda*) * count);
			for (size_t i = 0; i < count; i++) {
				YValue* val = pop(th);
				if (val->type == &th->runtime->LambdaType)
					lambdas[i] = (YLambda*) val;
				else
					lambdas[i] = NULL;
			}
			// If default lambda is defined then get it
			YLambda* defLmbd = NULL;
			if (iarg2 != -1) {
				YValue* val = getRegister(iarg2, th);
				if (val->type == &th->runtime->LambdaType)
					defLmbd = (YLambda*) val;
			}
			// Create overloaded lambda
			SET_REGISTER(
					(YValue*) newOverloadedLambda(lambdas, count, defLmbd, th),
					iarg0, th);

			// Free allocated resources
			free(lambdas);
		}
			break;
		case VM_NewComplexObject: {
			/*Pop mixin objects from stack and create complex object*/
			// Get mixin count and pop mixins
			size_t count = (size_t) iarg2;
			YObject** mixins = malloc(sizeof(YObject*) * count);
			for (size_t i = 0; i < count; i++) {
				YValue* val = pop(th);
				if (val->type == &th->runtime->ObjectType)
					mixins[i] = (YObject*) val;
				else
					mixins[i] = NULL;
			}
			// Get base object
			YValue* basev = getRegister(iarg1, th);
			YObject* base = NULL;
			if (basev->type == &th->runtime->ObjectType)
				base = (YObject*) basev;
			else
				base = th->runtime->newObject(NULL, th);
			// Create complex object and free allocated resources
			SET_REGISTER((YValue*) newComplexObject(base, mixins, count, th),
					iarg0, th);
			free(mixins);
		}
			break;

		case VM_GetField: {
			/*Read value property and store it in register*/
			YValue* val = getRegister(iarg1, th);
			if (val->type->oper.readProperty != NULL) {
				SET_REGISTER(val->type->oper.readProperty(iarg2, val, th), iarg0,
						th);
			} else
				SET_REGISTER(getNull(th), iarg0, th);
		}
			break;
		case VM_SetField: {
			/*Set objects field*/
			YValue* val = getRegister(iarg0, th);
			if (val->type == &th->runtime->ObjectType) {
				YObject* obj = (YObject*) val;
				obj->put(obj, iarg1, getRegister(iarg2, th), false, th);
			}
		}
			break;
		case VM_NewField: {
			/*Create new field in object*/
			YValue* val = getRegister(iarg0, th);
			if (val->type == &th->runtime->ObjectType) {
				YObject* obj = (YObject*) val;
				obj->put(obj, iarg1, getRegister(iarg2, th), true, th);
			}
		}
			break;
		case VM_DeleteField: {
			/*Delete field from object*/
			YValue* val = getRegister(iarg0, th);
			if (val->type == &th->runtime->ObjectType) {
				YObject* obj = (YObject*) val;
				obj->remove(obj, iarg1, th);
			}
		}
			break;
		case VM_ArrayGet: {
			/*Get index from value. If can't then throw exception*/
			YValue* val = getRegister(iarg1, th);
			YValue* val2 = getRegister(iarg2, th);
			// If value is array, but index is integer then
			// reads array element at index
			if (val->type == &th->runtime->ArrayType && val2->type == &th->runtime->IntType) {
				YArray* arr = (YArray*) val;
				size_t index = (size_t) ((YInteger*) val2)->value;
				SET_REGISTER(arr->get(arr, index, th), iarg0, th);
			} else if (val->type->oper.readIndex != NULL) {
				// Else calls readIndex on type(if readIndex is defined)
				SET_REGISTER(val->type->oper.readIndex(val, val2, th), iarg0,
						th);
			} else {
				throwException(L"AccesingNotAnArray", NULL, 0, th);
				SET_REGISTER(getNull(th), iarg0, th);
			}
		}
			break;
		case VM_ArraySet: {
			/*Set value to other value on index. If can't throw exception*/
			YValue* val = getRegister(iarg0, th);
			YValue* val2 = getRegister(iarg1, th);
			// If value if array, but index is integer
			// then assigns value to an array
			if (val->type == &th->runtime->ArrayType && val2->type == &th->runtime->IntType) {
				YArray* arr = (YArray*) val;
				size_t index = (size_t) ((YInteger*) val2)->value;
				arr->set(arr, index, getRegister(iarg2, th), th);
			} else if (val->type->oper.readIndex != NULL) {
				// Else calls writeIndex on type(if writeIndex is defined)
				val->type->oper.writeIndex(val, val2, getRegister(iarg2, th),
						th);
			} else {
				throwException(L"ModifyingNotAnArray", NULL, 0, th);
			}
		}
			break;
		case VM_ArrayDelete: {
			/*If value is array but index is integer set array index
			 * else throw an exception*/
			YValue* val = getRegister(iarg0, th);
			YValue* val2 = getRegister(iarg1, th);
			if (val->type == &th->runtime->ArrayType && val2->type == &th->runtime->IntType) {
				YArray* arr = (YArray*) val;
				size_t index = (size_t) ((YInteger*) val2)->value;
				arr->remove(arr, index, th);
			} else if (val->type->oper.removeIndex !=NULL) {
				val->type->oper.removeIndex(val, val2, th);
			} else {
				throwException(L"ModifyingNotAnArray", NULL, 0, th);
			}

		}
			break;

		case VM_Goto: {
			/*Get label id from argument, get label address and jump*/
			uint32_t addr = frame->proc->getLabel(frame->proc, iarg0)->value;
			frame->pc = addr;
			continue;
		}
			break;
		case VM_GotoIfTrue: {
			/*Get label id from argument, get label address and jump
			 * if condition is true*/
			YValue* bln = getRegister(iarg1, th);
			if (bln->type == &th->runtime->BooleanType && ((YBoolean*) bln)->value) {
				uint32_t addr = frame->proc->getLabel(frame->proc, iarg0)->value;
				frame->pc = addr;
				continue;
			}
		}
			break;
		case VM_GotoIfFalse: {
			/*Get label id from argument, get label address and jump
			 * if condition is false*/
			YValue* bln = getRegister(iarg1, th);
			if (bln->type == &th->runtime->BooleanType && !((YBoolean*) bln)->value) {
				uint32_t addr = frame->proc->getLabel(frame->proc, iarg0)->value;
				frame->pc = addr;
				continue;
			}
		}
			break;
		case VM_Jump: {
			/*Goto to an address*/
			frame->pc = iarg0;
			continue;
		}
			break;
		case VM_JumpIfTrue: {
			/*Goto to an address if condition is true*/
			YValue* bln = getRegister(iarg1, th);
			if (bln->type == &th->runtime->BooleanType && ((YBoolean*) bln)->value) {
				frame->pc = iarg0;
				continue;
			}
		}
			break;
		case VM_JumpIfFalse: {
			/*Goto to an address if condition is false*/
			YValue* bln = getRegister(iarg1, th);
			if (bln->type == &th->runtime->BooleanType && !((YBoolean*) bln)->value) {
				frame->pc = iarg0;
				continue;
			}
		}
			break;

		case VM_Throw: {
			/*Throw an exception*/
			th->exception = newException(getRegister(iarg0, th), th);
		}
			break;
		case VM_Catch: {
			/*Save current exception in register and
			 * set exception NULL*/
			SET_REGISTER(th->exception, iarg0, th);
			th->exception = NULL;
		}
			break;
		case VM_OpenCatch: {
			/*Add next catch address to frame catch stack.
			 * If exception is thrown then catch address being
			 * popped from stack and interpreter
			 * jump to it*/
			CatchBlock* cb = malloc(sizeof(CatchBlock));
			cb->prev = frame->catchBlock;
			cb->pc = iarg0;
			frame->catchBlock = cb;
		}
			break;
		case VM_CloseCatch: {
			/*Remove catch address from frame catch stack*/
			CatchBlock* cb = frame->catchBlock;
			frame->catchBlock = cb->prev;
			free(cb);
		}
			break;

		case VM_Nop: {
			/*Does nothing*/
		}
			break;

		case VM_Swap: {
			/*Swap two register values*/
			YValue* r1 = getRegister(iarg0, th);
			YValue* r2 = getRegister(iarg1, th);
			SET_REGISTER(r1, iarg1, th);
			SET_REGISTER(r2, iarg0, th);
		}
			break;
		case VM_Subsequence: {
			/*Get subsequence from value if subseq method
			 * is defined*/
			YValue* reg = getRegister(iarg0, th);
			YValue* tfrom = getRegister(iarg1, th);
			YValue* tto = getRegister(iarg2, th);
			if (tfrom->type == &th->runtime->IntType&&
				tto->type == &th->runtime->IntType&&
				reg->type->oper.subseq!=NULL) {
				size_t from = (size_t) ((YInteger*) tfrom)->value;
				size_t to = (size_t) ((YInteger*) tto)->value;
				SET_REGISTER(reg->type->oper.subseq(reg, from, to, th), iarg0,
						th);
			} else
				SET_REGISTER(getNull(th), iarg0, th);
		}
			break;
		case VM_Iterator: {
			/*Get iterator from value if it is iterable*/
			YValue* v = getRegister(iarg1, th);
			if (v->type->oper.iterator != NULL) {
				SET_REGISTER((YValue*) v->type->oper.iterator(v, th), iarg0, th);\
			}
			else {
				SET_REGISTER(getNull(th), iarg0, th);
			}

		}
			break;
		case VM_Iterate: {
			/*If iterator has next value than get it and save
			 * to register. If iterator doesn't has next value
			 * then jump to a label*/
			YValue* v = getRegister(iarg1, th);
			YValue* value = NULL;
			if (v->type->oper.iterator != NULL) {
				YoyoIterator* iter = v->type->oper.iterator(v, th);
				if (iter->hasNext(iter, th))
					value = iter->next(iter, th);
			}
			if (value == NULL) {
				uint32_t addr = frame->proc->getLabel(frame->proc, iarg2)->value;
				frame->pc = addr;
			} else
				SET_REGISTER(value, iarg0, th);
		}
			break;
		case VM_NewInterface: {
			/*Build new interface*/
			YoyoAttribute* attrs = calloc(1, sizeof(YoyoAttribute) * iarg2);
			// Pop interface parents
			YoyoInterface** parents = calloc(1, sizeof(YoyoInterface*) * iarg1);
			for (int32_t i = 0; i < iarg1; i++) {
				YValue* val = pop(th);
				YoyoType* type = NULL;
				if (val->type == &th->runtime->DeclarationType)
					type = (YoyoType*) val;
				else
					type = val->type->TypeConstant;
				parents[i] =
						type->type == InterfaceDT ?
								(YoyoInterface*) type : NULL;
			}
			// Pop interface fields
			for (int32_t i = 0; i < iarg2; i++) {
				attrs[i].id = popInt(th);
				YValue* val = pop(th);
				YoyoType* type = NULL;
				if (val->type == &th->runtime->DeclarationType)
					type = (YoyoType*) val;
				else
					type = val->type->TypeConstant;
				attrs[i].type = type;
			}
			// Build interface and free allocated resources
			SET_REGISTER(
					(YValue*) newInterface(parents, (size_t) iarg1, attrs,
							(size_t) iarg2, th), iarg0, th);
			free(attrs);
			free(parents);
		}
			break;
		case VM_ChangeType: {
			/*Change field type*/
			YValue* val = getRegister(iarg2, th);
			YoyoType* type = NULL;
			if (val->type == &th->runtime->DeclarationType)
				type = (YoyoType*) val;
			else
				type = val->type->TypeConstant;
			YValue* o = getRegister(iarg0, th);
			if (o->type == &th->runtime->ObjectType) {
				YObject* obj = (YObject*) o;
				obj->setType(obj, iarg1, type, th);
			}
		}
			break;
		case VM_GotoIfEquals: {
			YValue* v1 = getRegister(iarg1, th);
			YValue* v2 = getRegister(iarg2, th);
			int cmp = v1->type->oper.compare(v1, v2, th);
			if ((cmp & COMPARE_EQUALS) != 0) {
				uint32_t addr = frame->proc->getLabel(frame->proc, iarg0)->value;
				frame->pc = addr;
				continue;
			}
		}
		break;
		case VM_JumpIfEquals: {
			YValue* v1 = getRegister(iarg1, th);
			YValue* v2 = getRegister(iarg2, th);
			int cmp = v1->type->oper.compare(v1, v2, th);
			if ((cmp & COMPARE_EQUALS) != 0) {
				frame->pc = iarg0;
				continue;
			}
		}
		break;
		case VM_GotoIfNotEquals: {
			YValue* v1 = getRegister(iarg1, th);
			YValue* v2 = getRegister(iarg2, th);
			int cmp = v1->type->oper.compare(v1, v2, th);
			if ((cmp & COMPARE_NOT_EQUALS) != 0) {
				uint32_t addr = frame->proc->getLabel(frame->proc, iarg0)->value;
				frame->pc = addr;
				continue;
			}
		}
		break;
		case VM_JumpIfNotEquals: {
			YValue* v1 = getRegister(iarg1, th);
			YValue* v2 = getRegister(iarg2, th);
			int cmp = v1->type->oper.compare(v1, v2, th);
			if ((cmp & COMPARE_NOT_EQUALS) != 0) {
				frame->pc = iarg0;
				continue;
			}
		}
		break;
		case VM_GotoIfGreater: {
			YValue* v1 = getRegister(iarg1, th);
			YValue* v2 = getRegister(iarg2, th);
			int cmp = v1->type->oper.compare(v1, v2, th);
			if ((cmp & COMPARE_GREATER) != 0) {
				uint32_t addr = frame->proc->getLabel(frame->proc, iarg0)->value;
				frame->pc = addr;
				continue;
			}
		}
		break;
		case VM_JumpIfGreater: {
			YValue* v1 = getRegister(iarg1, th);
			YValue* v2 = getRegister(iarg2, th);
			int cmp = v1->type->oper.compare(v1, v2, th);
			if ((cmp & COMPARE_GREATER) != 0) {
				frame->pc = iarg0;
				continue;
			}
		}
		break;
		case VM_GotoIfLesser: {
			YValue* v1 = getRegister(iarg1, th);
			YValue* v2 = getRegister(iarg2, th);
			int cmp = v1->type->oper.compare(v1, v2, th);
			if ((cmp & COMPARE_LESSER) != 0) {
				uint32_t addr = frame->proc->getLabel(frame->proc, iarg0)->value;
				frame->pc = addr;
				continue;
			}
		}
		break;
		case VM_JumpIfLesser: {
			YValue* v1 = getRegister(iarg1, th);
			YValue* v2 = getRegister(iarg2, th);
			int cmp = v1->type->oper.compare(v1, v2, th);
			if ((cmp & COMPARE_LESSER) != 0) {
				frame->pc = iarg0;
				continue;
			}
		}
		break;
		case VM_GotoIfNotLesser: {
			YValue* v1 = getRegister(iarg1, th);
			YValue* v2 = getRegister(iarg2, th);
			int cmp = v1->type->oper.compare(v1, v2, th);
			if ((cmp & COMPARE_GREATER_OR_EQUALS) != 0) {
				uint32_t addr = frame->proc->getLabel(frame->proc, iarg0)->value;
				frame->pc = addr;
				continue;
			}
		}
		break;
		case VM_JumpIfNotLesser: {
			YValue* v1 = getRegister(iarg1, th);
			YValue* v2 = getRegister(iarg2, th);
			int cmp = v1->type->oper.compare(v1, v2, th);
			if ((cmp & COMPARE_GREATER_OR_EQUALS) != 0) {
				frame->pc = iarg0;
				continue;
			}
		}
		break;
		case VM_GotoIfNotGreater: {
			YValue* v1 = getRegister(iarg1, th);
			YValue* v2 = getRegister(iarg2, th);
			int cmp = v1->type->oper.compare(v1, v2, th);
			if ((cmp & COMPARE_LESSER_OR_EQUALS) != 0) {
				uint32_t addr = frame->proc->getLabel(frame->proc, iarg0)->value;
				frame->pc = addr;
				continue;
			}
		}
		break;
		case VM_JumpIfNotGreater: {
			YValue* v1 = getRegister(iarg1, th);
			YValue* v2 = getRegister(iarg2, th);
			int cmp = v1->type->oper.compare(v1, v2, th);
			if ((cmp & COMPARE_LESSER_OR_EQUALS) != 0) {
				frame->pc = iarg0;
				continue;
			}
		}
		break;
		case VM_CheckType: {
			YValue* value = getRegister(iarg0, th);
			YValue* tv = getRegister(iarg1, th);
			YoyoType* type = NULL;
			if (tv->type == &th->runtime->DeclarationType)
				type = (YoyoType*) tv;
			else
				type = tv->type->TypeConstant;
			if (!type->verify(type, value, th)) {
				wchar_t* wcs = getSymbolById(&th->runtime->symbols, iarg2);
				throwException(L"WrongFieldType", &wcs, 1, th);
			}
		}
		break;
		}
		/*If there is an exception then get last catch block
		 * and jump to an address. If catch stack is empty
		 * then return from procedure*/
		if (th->exception != NULL) {
			if (frame->catchBlock != NULL) {
				frame->pc = frame->proc->getLabel(frame->proc,
						frame->catchBlock->pc)->value;
				continue;
			} else
				return getNull(th);
		}
		frame->pc += 13;
	}
	return getNull(th);
}