Пример #1
0
int check_do_while(is_do_while* node, is_label* label)
{
	int errors = 0;

	int mylabel = ++label_counter; /* setting label for use with loops and break/continue */

	if (label)
		node->scope = scope_new(symbol_new_loop(label->name, node->line, mylabel), false);
	else
		node->scope = scope_new(symbol_new_loop(NULL, node->line, mylabel), false);
		
	scope_push(node->scope);
		errors += check_stmt(node->body);
		if (errors == 0)
			node->terminates = node->body->terminates;

		errors += check_expr(node->cond);
		if (errors == 0)
		{
			if (!type_native_assign_able(t_type_native_bool, node->cond->s_type))
			{
				errors++;
				pretty_error(node->line, "invalid do..while condition (must be boolean)");
			}
		}
	scope_pop();
	return errors;
}
Пример #2
0
static HRESULT invoke_source(script_ctx_t *ctx, FunctionInstance *function, IDispatch *this_obj, unsigned argc, jsval_t *argv,
        jsval_t *r)
{
    jsdisp_t *var_disp, *arg_disp;
    exec_ctx_t *exec_ctx;
    scope_chain_t *scope;
    HRESULT hres;

    if(ctx->state == SCRIPTSTATE_UNINITIALIZED || ctx->state == SCRIPTSTATE_CLOSED) {
        WARN("Script engine state does not allow running code.\n");
        return E_UNEXPECTED;
    }

    if(!function->func_code) {
        FIXME("no source\n");
        return E_FAIL;
    }

    hres = create_var_disp(ctx, function, argc, argv, &var_disp);
    if(FAILED(hres))
        return hres;

    hres = create_arguments(ctx, function, var_disp, argc, argv, &arg_disp);
    if(FAILED(hres)) {
        jsdisp_release(var_disp);
        return hres;
    }

    hres = jsdisp_propput(var_disp, argumentsW, PROPF_DONTDELETE, jsval_obj(arg_disp));
    if(FAILED(hres)) {
        jsdisp_release(arg_disp);
        jsdisp_release(var_disp);
        return hres;
    }

    hres = scope_push(function->scope_chain, var_disp, to_disp(var_disp), &scope);
    if(SUCCEEDED(hres)) {
        hres = create_exec_ctx(ctx, this_obj, var_disp, scope, FALSE, &exec_ctx);
        scope_release(scope);

        if(SUCCEEDED(hres)) {
            jsdisp_t *prev_args;

            prev_args = function->arguments;
            function->arguments = arg_disp;
            hres = exec_source(exec_ctx, function->code, function->func_code, FALSE, r);
            function->arguments = prev_args;

            exec_release(exec_ctx);
        }
    }

    /* Reset arguments value to cut the reference cycle. Note that since all activation contexts have
     * their own arguments property, it's impossible to use prototype's one during name lookup */
    jsdisp_propput_name(var_disp, argumentsW, jsval_undefined());

    jsdisp_release(arg_disp);
    jsdisp_release(var_disp);
    return hres;
}
Пример #3
0
int check_while(is_while* node, is_label* label)
{
	int errors = 0;
	char *string;

	int mylabel = ++label_counter; /* setting label for use with loops and break/continue */
	
	if (label)
		node->scope = scope_new(symbol_new_loop(label->name, node->line, mylabel), false);
	else
		node->scope = scope_new(symbol_new_loop(NULL, node->line, mylabel), false);
		
	scope_push(node->scope);
		errors += check_expr(node->cond);
		if (errors == 0)
		{
			if (!type_native_assign_able(t_type_native_bool, node->cond->s_type))
			{
				errors++;
				pretty_error(node->line, "invalid while condition: expected boolean, got %s", string = string_type_decl(node->cond->s_type));
				free(string);
			}
		}

		errors += check_stmt(node->body);
		node->terminates = node->body->terminates;
	scope_pop();
	
	return errors;
}
Пример #4
0
static HRESULT invoke_source(FunctionInstance *function, IDispatch *this_obj, LCID lcid, DISPPARAMS *dp,
        VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
{
    DispatchEx *var_disp;
    exec_ctx_t *exec_ctx;
    scope_chain_t *scope;
    HRESULT hres;

    if(!function->source) {
        FIXME("no source\n");
        return E_FAIL;
    }

    hres = create_var_disp(function, lcid, dp, ei, caller, &var_disp);
    if(FAILED(hres))
        return hres;

    hres = scope_push(function->scope_chain, var_disp, &scope);
    if(SUCCEEDED(hres)) {
        hres = create_exec_ctx(this_obj, var_disp, scope, &exec_ctx);
        scope_release(scope);
    }
    if(FAILED(hres))
        return hres;

    hres = exec_source(exec_ctx, function->parser, function->source, ei, retv);
    exec_release(exec_ctx);

    return hres;
}
Пример #5
0
main()
{
	int choice;
	char buffer[32];

	scope_t *top_scope = NULL;
	node_t *tmp = NULL;
	
	fprintf(stderr, "0.search 1.search_all 2.insert 3.new_scope 4.del_scope \n");
	while (1) {
		scanf("%d", &choice);
		switch(choice) {
		case 0:
			scanf("%s", buffer);
			tmp = scope_search(top_scope, buffer);
			if (tmp != NULL) {
				fprintf(stderr, "Found[%s]\n", tmp->name);
			}
			else {
				fprintf(stderr, "Not found[%s]\n", buffer);
			}
			break;

		case 1:
			scanf("%s", buffer);
			tmp = scope_search_all(top_scope, buffer);
			if (tmp != NULL) {
				fprintf(stderr, "Found[%s]\n", tmp->name);
			}
			else {
				fprintf(stderr, "Not found[%s]\n", buffer);
			}
			break;

		case 2:
			scanf("%s", buffer);
			tmp = scope_insert(top_scope, buffer);
			if (tmp != NULL) {
				fprintf(stderr, "Insert[%s]\n", tmp->name);
			}
			else {
				fprintf(stderr, "Cannot Insert[%s]\n", buffer);
			}
			break;

		case 3:
			top_scope = scope_push(top_scope);
			break;

		case 4:
			top_scope = scope_pop(top_scope);
			break;
		}
	}
}
Пример #6
0
static HRESULT invoke_source(script_ctx_t *ctx, FunctionInstance *function, IDispatch *this_obj, unsigned argc, jsval_t *argv,
        BOOL is_constructor, BOOL caller_execs_source, jsval_t *r)
{
    jsdisp_t *var_disp, *arg_disp;
    scope_chain_t *scope;
    HRESULT hres;

    if(ctx->state == SCRIPTSTATE_UNINITIALIZED || ctx->state == SCRIPTSTATE_CLOSED) {
        WARN("Script engine state does not allow running code.\n");
        return E_UNEXPECTED;
    }

    if(!function->func_code) {
        FIXME("no source\n");
        return E_FAIL;
    }

    hres = create_var_disp(ctx, function, argc, argv, &var_disp);
    if(FAILED(hres))
        return hres;

    hres = create_arguments(ctx, function, var_disp, argc, argv, &arg_disp);
    if(FAILED(hres)) {
        jsdisp_release(var_disp);
        return hres;
    }

    hres = jsdisp_propput(var_disp, argumentsW, PROPF_DONTDELETE, jsval_obj(arg_disp));
    if(FAILED(hres)) {
        jsdisp_release(arg_disp);
        jsdisp_release(var_disp);
        return hres;
    }

    hres = scope_push(function->scope_chain, var_disp, to_disp(var_disp), &scope);
    if(SUCCEEDED(hres)) {
        DWORD exec_flags = 0;

        if(caller_execs_source)
            exec_flags |= EXEC_RETURN_TO_INTERP;
        if(is_constructor)
            exec_flags |= EXEC_CONSTRUCTOR;
        hres = exec_source(ctx, exec_flags, function->code, function->func_code, scope, this_obj,
                &function->dispex, var_disp, arg_disp, r);

        scope_release(scope);
    }

    jsdisp_release(arg_disp);
    jsdisp_release(var_disp);
    return hres;
}
Пример #7
0
static HRESULT invoke_source(script_ctx_t *ctx, FunctionInstance *function, IDispatch *this_obj, DISPPARAMS *dp,
        VARIANT *retv, jsexcept_t *ei, IServiceProvider *caller)
{
    jsdisp_t *var_disp, *arg_disp;
    exec_ctx_t *exec_ctx;
    scope_chain_t *scope;
    HRESULT hres;

    if(!function->source) {
        FIXME("no source\n");
        return E_FAIL;
    }

    hres = create_arguments(ctx, to_disp(&function->dispex),
            dp, ei, caller, &arg_disp);
    if(FAILED(hres))
        return hres;

    hres = create_var_disp(ctx, function, arg_disp, dp, ei, caller, &var_disp);
    if(FAILED(hres)) {
        jsdisp_release(arg_disp);
        return hres;
    }

    hres = scope_push(function->scope_chain, var_disp, &scope);
    if(SUCCEEDED(hres)) {
        hres = create_exec_ctx(ctx, this_obj, var_disp, scope, FALSE, &exec_ctx);
        scope_release(scope);
    }
    jsdisp_release(var_disp);
    if(SUCCEEDED(hres)) {
        jsdisp_t *prev_args;

        prev_args = function->arguments;
        function->arguments = arg_disp;
        hres = exec_source(exec_ctx, function->parser, function->source, FALSE, ei, retv);
        function->arguments = prev_args;

        jsdisp_release(arg_disp);
        exec_release(exec_ctx);
    }

    return hres;
}
Пример #8
0
int main(int argc, char **argv) {
    NODE *static_scope = scope_push(NIL);
    NODE *macro_map = binmap(newSYMBOL(intern("NIL")),NIL);
    for (int i = 1; i < argc; i++) {
        debug("loading file: %s\n",argv[i]);
        FILE *f = fopen(argv[i],"rb");
        if (!f) error("Could not open file %s",argv[i]);
        fseek(f, 0, SEEK_END);
        size_t len = ftell(f);
        rewind(f);
        char *prog_str = malloc(len+1);
        fread(prog_str,1,len,f);
        prog_str[len] = '\0';
        fclose(f);
        debug("program(%u):\n%s",(unsigned int)len,prog_str);
        VALUE *val = eval_string(prog_str,static_scope,macro_map);
        decRef(val);
    }
}
Пример #9
0
int check_for(is_for* node, is_label* label)
{
	int errors = 0, cond_errors;
	char* typeA;

	int mylabel = ++label_counter; /* setting label for use with loops and break/continue */

	if (label)
		node->scope = scope_new(symbol_new_loop(label->name, node->line, mylabel), false);
	else
		node->scope = scope_new(symbol_new_loop(NULL, node->line, mylabel), false);
		
	scope_push(node->scope);
		if (node->init)
			errors += check_for_init(node->init);

		if (node->cond)
		{
			cond_errors = check_for_cond(node->cond);
			if (cond_errors == 0)
			{
				if (!type_native_assign_able(t_type_native_bool, node->cond->s_type))
				{
					cond_errors++;
					pretty_error(node->line, "for conditional is not boolean (is of type %s)", typeA = string_type_decl(node->cond->s_type));
					free(typeA);
				}
			}
			errors += cond_errors;
		}
	
		if (node->inc)
			errors += check_for_inc(node->inc);

		errors += check_stmt(node->body);

		if (errors == 0)
			node->terminates = (node->body ? node->body->terminates : true);
	scope_pop();
 
	return errors;
}
Пример #10
0
static HRESULT invoke_source(script_ctx_t *ctx, FunctionInstance *function, IDispatch *this_obj, unsigned argc, jsval_t *argv,
        jsval_t *r)
{
    jsdisp_t *var_disp, *arg_disp;
    exec_ctx_t *exec_ctx;
    scope_chain_t *scope;
    HRESULT hres;

    if(!function->func_code) {
        FIXME("no source\n");
        return E_FAIL;
    }

    hres = create_arguments(ctx, to_disp(&function->dispex), argc, argv, &arg_disp);
    if(FAILED(hres))
        return hres;

    hres = create_var_disp(ctx, function, arg_disp, argc, argv, &var_disp);
    if(FAILED(hres)) {
        jsdisp_release(arg_disp);
        return hres;
    }

    hres = scope_push(function->scope_chain, var_disp, to_disp(var_disp), &scope);
    if(SUCCEEDED(hres)) {
        hres = create_exec_ctx(ctx, this_obj, var_disp, scope, FALSE, &exec_ctx);
        scope_release(scope);
    }
    jsdisp_release(var_disp);
    if(SUCCEEDED(hres)) {
        jsdisp_t *prev_args;

        prev_args = function->arguments;
        function->arguments = arg_disp;
        hres = exec_source(exec_ctx, function->code, function->func_code, FALSE, r);
        function->arguments = prev_args;
    }

    jsdisp_release(arg_disp);
    exec_release(exec_ctx);
    return hres;
}
Пример #11
0
int check_switch(is_switch* node)
{
	int errors = 0;
	int mylabel = ++label_counter; /* setting label for use with break */
	char *type;

	if (node->label)
		errors += check_label(node->label);

	errors += check_expr(node->expr);

	if (errors == 0)
	{
		if (node->expr->s_type->type == t_type_decl_array_decl)
		{
			errors++;

			type = string_type_decl(node->expr->s_type);
			pretty_error(node->line, "switch statement expression must be of object type (got %s)", type);
			free(type);
		}
	}

	if (errors == 0)
	{
		if (node->label)
			node->scope = scope_new(symbol_new_switch(node->label->name, node->line, mylabel, node->expr->s_type->data.type_object, symtab->framepos++), false);
		else
			node->scope = scope_new(symbol_new_switch(NULL, node->line, mylabel, node->expr->s_type->data.type_object, symtab->framepos++), false);

		scope_push(node->scope);
			check_switch_stmt_list(node->list, node);

			if (errors == 0)
				node->terminates = (node->list ? node->list->terminates : true);
		scope_pop();
 	}

	return errors;
}
Пример #12
0
static void interpret_routine(struct program *program, struct routine *routine, struct scope **scope, int arg_count, struct var **args)
{
	assert(routine);
	if (routine->library_routine) {
		routine->library_routine(*scope, arg_count, args);
		scope_gc(*scope);
		return;
	}
	*scope = scope_push(*scope, routine->var_count);

	for (int i = 0; i < arg_count && i < routine->parameter_count; i++) {
		scope_refer(*scope, i, args[i]);
	}

	int exit_code = interpret_stmts(program, routine->stmt_count, routine->stmts, scope);
	assert(exit_code == EXIT_CODE_RETURN || exit_code == EXIT_CODE_FALLTHROUGH);

	*scope = scope_pop(*scope);
	if (*scope) {
		scope_gc(*scope);
	}
}
Пример #13
0
int check_class_def(is_class_def* node)
{
	int errors = 0;
	SYMBOL* symbol;

	symbol = scope_lookup(symtab, node->id->name, t_symbol_class);
	if (symbol)
	{
		errors++;
		pretty_error(node->line, "class \"%s\" is already defined (previous declaration was here: %d)", node->id->name, symbol->line);
	} else
		scope_insert(symtab, symbol = symbol_new_class(node->id->name, node->line));

	node->scope = scope_new(symbol, true);

	/*
		FIXME:
		this should be in application and not in class def,
		because theoretically class should be able to access other classes
	*/
	scope_push(node->scope);
		errors += check_class_stmt_list(node->body, true);

		if (errors == 0)
		{
			symbol = scope_lookup(symtab, "main", t_symbol_func);
			if (!symbol)
			{
				errors++;
				pretty_error(node->line, "missing main entry point");
			}
		}
		errors += check_class_stmt_list(node->body, false);
	scope_pop();

	return errors;
}
Пример #14
0
int check_func_def(is_func_def* node, bool first_pass)
{
	SYMBOL* symbol;
	SCOPE* tempscope;
	int label;
	int errors = 0;
	is_type_decl *tmpType = NULL;

	if (first_pass)
	{
		errors += check_type_decl(node->type);

		symbol = scope_lookup(symtab, node->id->name, t_symbol_func);
		if (symbol)
		{
			pretty_error(node->line, "symbol \"%s\" is already defined (previous declaration was here: %d)", node->id->name, symbol->line);
			errors++;
		} else
		{
			tempscope = scope_new(NULL, false);
			scope_push(tempscope);
				errors += check_func_def_args(node->args);
			scope_pop();
			
			if (strcmp(node->id->name, "main") == 0)
			{
				label = 0;

				if (node->args) /* no args is valid */
				{
					if (node->args->length == 1) /* main may must not have more than two arguments */
					{
						tmpType = insert_type_decl_array(insert_array_decl(insert_type_object(t_type_native_string), new_dims_empty_list(0, 1))); /* must be an array of Strings */

						if (!type_type_equal(tmpType,node->args->node->type))
						{
							errors++;
							pretty_error(node->line, "main function arguments do not match any valid prototypes");
						}

						free_type_decl(tmpType);
					} else
					{
						errors++;
						pretty_error(node->line, "main function arguments do not match any valid prototypes");
					}
				}

				tmpType = insert_type_decl_object(insert_type_object(t_type_native_int)); /* return value must be int or void */

				if (!type_type_equal(tmpType,node->type))
				{
					free_type_decl(tmpType);

					tmpType = new_type_decl_void(0); /* check for void */

					if (!type_type_equal(tmpType,node->type)) /* none; errors occurred */
					{
						errors++;
						pretty_error(node->line, "main function return type does not match any valid types (nor int nor void)");
					}
				}
				
				free_type_decl(tmpType);
			} else
				label = ++label_counter;

			symbol = symbol_new_func(node->id->name, node->line, node->type, node->args, label);
			scope_delete(tempscope);

			scope_insert(symtab, symbol);

			node->scope = scope_new(symbol, false);
		}
	} else
	{
		scope_push(node->scope);
			errors += check_func_def_args(node->args); /* this will not give errors */
			errors += check_stmt_list(node->body);
			
			if ((!node->body || !node->body->terminated) &&
				!(node->type->type == t_type_decl_type_object && node->type->data.type_object->type == t_type_native_void))
			{
				pretty_error(node->line, "reached end of non void function");
				errors++;		
			}
		scope_pop();
	}

	return errors;
}
Пример #15
0
int check_stmt(is_stmt* node)
{
	int errors = 0;

	/* ; empty statement */
	if (!node)
		return 0;

	switch (node->type)
	{
		case t_stmt_stmt_list:
			node->data.stmt_list.scope = scope_new(NULL, false);
			scope_push(node->data.stmt_list.scope);
				errors += check_stmt_list(node->data.stmt_list.list);
			scope_pop();

			if (errors == 0)
				node->terminates = node->data.stmt_list.list->terminated;
		break;

		case t_stmt_var_stmt:
			errors += check_var_stmt(node->data.var, false);
		break;

		case t_stmt_assign:
			errors += check_assign_op(node->data.assign);
		break;

		case t_stmt_incr:
			errors += check_incr_op(node->data.incr);
		break;

		case t_stmt_if:
			errors += check_if(node->data.if_stmt);
			if (errors == 0)
				node->terminates = node->data.if_stmt->terminates;
		break;

		case t_stmt_loop:
			errors += check_loop_stmt(node->data.loop);
			if (errors == 0)
				node->terminates = node->data.loop->terminates;
		break;

		case t_stmt_func_call:
			errors += check_func_call(node->data.func_call);
		break;

		case t_stmt_switch:
			errors += check_switch(node->data.switch_stmt);

			if (errors == 0)
				node->terminates = node->data.switch_stmt->terminates;
		break;

		case t_stmt_break:
			errors += check_break(node->data.break_stmt);
			node->terminates = true;
		break;

		case t_stmt_continue:
			errors += check_continue(node->data.continue_stmt);
			node->terminates = true;
		break;
		
		case t_stmt_return:
			errors += check_return(node->data.return_stmt);
			node->terminates = true;
		break;
	}

	return errors;
}