Beispiel #1
0
static EEL_object *eel_load_buffer_nc(EEL_vm *vm,
		const char *source, unsigned len, EEL_sflags flags)
{
	EEL_state *es = VMP->state;
	EEL_value v;
	EEL_object *m;
	EEL_xno x = eel_o_construct(es->vm, EEL_CMODULE, NULL, 0, &v);
	if(x)
		return NULL;
	m = v.objref.v;
	eel_try(es)
		load_buffer(vm, o2EEL_module(m), source, len);
	eel_except
	{
		eel_o_disown_nz(m);
		return NULL;
	}
	return m;
}
Beispiel #2
0
EEL_vm *eel_open(int argc, const char *argv[])
{
#ifdef DEBUG
	int i;
#endif
	EEL_xno x;
	EEL_value v;
	EEL_vm *vm;
	EEL_state *es = (EEL_state *)calloc(1, sizeof(EEL_state));
	if(!es)
		return NULL;

	if(eel_sbuffer_open(es))
	{
		eel_msg(es, EEL_EM_IERROR, "Could not allocate"
				" compiler API string buffers!\n");
		es_close(es);
		return NULL;
	}

	es->last_module_id = -1;

	vm = es->vm = eel_vm_open(es, EEL_INITHEAP);
	if(!vm)
	{
		eel_msg(es, EEL_EM_IERROR, "Could not initialize"
				" virtual machine!\n");
		es_close(es);
		return NULL;
	}

	x = eel_cast_open(es);
	if(x)
	{
		eel_msg(es, EEL_EM_IERROR, "Could not initialize"
				" type casting subsystem!\n");
		es_close(es);
		return NULL;
	}

	/* Built-in classes */
	eel_try(es)
	{
		EEL_symbol *s;

		/* Bootstrap the class system */
		eel_register_class(vm, EEL_COBJECT, "object", -1,
				NULL, NULL, NULL);
		eel_cclass_register(vm);
		eel_cstring_register(vm);
		eel_o_own(es->classes[EEL_CCLASS]);	/* object is a class */

		/* Set up symbol table. (Needs CSTRING!) */
		es->root_symtab = eel_s_add(es, NULL, "root_namespace",
				EEL_SBODY);
		if(!es->root_symtab)
		{
			eel_msg(es, EEL_EM_IERROR, "Could not add"
					" root_namespace symbol!\n");
			es_close(es);
			eel_done(es);
			return NULL;
		}

		/* Name the classes that were installed before CSTRING */
		eel_register_class(vm, EEL_COBJECT, "object", -1,
				NULL, NULL, NULL);
		eel_cclass_register(vm);

		/*
		 * Add 'string' to the compiler symbol table,
		 * as that couldn't be done before. (No symbol table! :-)
		 */
		s = eel__register(vm, "string", EEL_SCLASS);
		if(s)
		{
			s->v.object = es->classes[EEL_CSTRING];
			eel_o_own(s->v.object);
			eel_register_essx(vm, EEL_CSTRING, s);
		}

		/* Register (other) base classes */
		eel_register_class(vm, EEL_CVALUE, "value", -1,
				NULL, NULL, NULL);

		/* Register value "classes" */
		eel_register_class(vm, EEL_TNIL, "\001nil", EEL_CVALUE,
				NULL, NULL, NULL);
		eel_register_class(vm, EEL_TREAL, "real", EEL_CVALUE,
				NULL, NULL, NULL);
		eel_register_class(vm, EEL_TINTEGER, "integer", EEL_CVALUE,
				NULL, NULL, NULL);
		eel_register_class(vm, EEL_TBOOLEAN, "boolean", EEL_CVALUE,
				NULL, NULL, NULL);
		eel_register_class(vm, EEL_TTYPEID, "typeid", EEL_CVALUE,
				NULL, NULL, NULL);
		eel_register_class(vm, EEL_TOBJREF, "\001objref", EEL_CVALUE,
				NULL, NULL, NULL);
		eel_register_class(vm, EEL_TWEAKREF, "\001weakref", EEL_CVALUE,
				NULL, NULL, NULL);

		/* Register the real classes */
		eel_cfunction_register(vm);
		eel_cmodule_register(vm);
		eel_carray_register(vm);
		eel_ctable_register(vm);
		eel_cvector_register(vm);
		eel_cdstring_register(vm);
	}
	eel_except
	{
		eel_msg(es, EEL_EM_IERROR, "Could not register"
				" built-in classes!\n");
		es_close(es);
		return NULL;
	}

	eel_cast_init(es);

	/* Module name table for circular import detection */
	x = eel_o_construct(vm, EEL_CTABLE, NULL, 0, &v);
	if(x)
	{
		eel_msg(es, EEL_EM_IERROR, "Could not create"
				" module name table!\n");
		es_close(es);
		return NULL;
	}
	es->modnames = v.objref.v;
	SETNAME(es->modnames, "Module Name Table");

	/* Module table */
	x = eel_o_construct(vm, EEL_CTABLE, NULL, 0, &v);
	if(x)
	{
		eel_msg(es, EEL_EM_IERROR, "Could not create module table!\n");
		es_close(es);
		return NULL;
	}
	es->modules = v.objref.v;
	SETNAME(es->modules, "Shared Module Table");

	/* 'environment' table */
	if(init_env_table(es))
	{
		es_close(es);
		return NULL;
	}

	/* Directives */
	eel_register_keyword(vm, "include", TK_KW_INCLUDE);
	eel_register_keyword(vm, "import", TK_KW_IMPORT);
	eel_register_keyword(vm, "as", TK_KW_AS);
	eel_register_keyword(vm, "end", TK_KW_END);
	eel_register_keyword(vm, "eelversion", TK_KW_EELVERSION);

	/* Flow control keywords */
	eel_register_keyword(vm, "return", TK_KW_RETURN);
	eel_register_keyword(vm, "if", TK_KW_IF);
	eel_register_keyword(vm, "else", TK_KW_ELSE);
	eel_register_keyword(vm, "switch", TK_KW_SWITCH);
	eel_register_keyword(vm, "case", TK_KW_CASE);
	eel_register_keyword(vm, "default", TK_KW_DEFAULT);
	eel_register_keyword(vm, "for", TK_KW_FOR);
	eel_register_keyword(vm, "do", TK_KW_DO);
	eel_register_keyword(vm, "while", TK_KW_WHILE);
	eel_register_keyword(vm, "until", TK_KW_UNTIL);
	eel_register_keyword(vm, "break", TK_KW_BREAK);
	eel_register_keyword(vm, "continue", TK_KW_CONTINUE);
	eel_register_keyword(vm, "repeat", TK_KW_REPEAT);

	eel_register_keyword(vm, "try", TK_KW_TRY);
	eel_register_keyword(vm, "untry", TK_KW_UNTRY);
	eel_register_keyword(vm, "except", TK_KW_EXCEPT);
	eel_register_keyword(vm, "throw", TK_KW_THROW);
	eel_register_keyword(vm, "retry", TK_KW_RETRY);

	/* Qualifier keywords */
	eel_register_keyword(vm, "local", TK_KW_LOCAL);
	eel_register_keyword(vm, "static", TK_KW_STATIC);
	eel_register_keyword(vm, "upvalue", TK_KW_UPVALUE);
	eel_register_keyword(vm, "export", TK_KW_EXPORT);
	eel_register_keyword(vm, "shadow", TK_KW_SHADOW);
	eel_register_keyword(vm, "constant", TK_KW_CONSTANT);

	/* Declaration keywords */
	eel_register_keyword(vm, "procedure", TK_KW_PROCEDURE);

	/* Special values */
	eel_register_keyword(vm, "true", TK_KW_TRUE);
	eel_register_keyword(vm, "false", TK_KW_FALSE);
	eel_register_keyword(vm, "nil", TK_KW_NIL);

	/* Special variables and operators */
	eel_register_keyword(vm, "arguments", TK_KW_ARGUMENTS);
	eel_register_keyword(vm, "tuples", TK_KW_TUPLES);
	eel_register_keyword(vm, "specified", TK_KW_SPECIFIED);
	eel_register_keyword(vm, "exception", TK_KW_EXCEPTION);

	/* Unary operators */
	eel_register_unop(vm, "-", EEL_OP_NEG, 100, 0);
	eel_register_unop(vm, "typeof", EEL_OP_TYPEOF, 100, 0);
	eel_register_unop(vm, "sizeof", EEL_OP_SIZEOF, 100, 0);
	eel_register_unop(vm, "clone", EEL_OP_CLONE, 100, 0);

	/* Unary bitwise operations */
	eel_register_unop(vm, "~", EEL_OP_BNOT, 100, 0);

	/* Unary boolean operators */
	eel_register_unop(vm, "not", EEL_OP_NOT, 25, 0);

	/* Arithmetics */
	eel_register_binop(vm, "**", EEL_OP_POWER, 90, EOPF_RIGHT);
	eel_register_binop(vm, "%", EEL_OP_MOD, 70, 0);
	eel_register_binop(vm, "/", EEL_OP_DIV, 70, 0);
	eel_register_binop(vm, "*", EEL_OP_MUL, 70, 0);
	eel_register_binop(vm, "-", EEL_OP_SUB, 60, 0);
	eel_register_binop(vm, "+", EEL_OP_ADD, 60, 0);

	/* Vector arithmetics */
	eel_register_binop(vm, "#**", EEL_OP_VPOWER, 90, EOPF_RIGHT);
	eel_register_binop(vm, "#%", EEL_OP_VMOD, 70, 0);
	eel_register_binop(vm, "#/", EEL_OP_VDIV, 70, 0);
	eel_register_binop(vm, "#*", EEL_OP_VMUL, 70, 0);
	eel_register_binop(vm, "#-", EEL_OP_VSUB, 60, 0);
	eel_register_binop(vm, "#+", EEL_OP_VADD, 60, 0);

	/* Bitwise operators */
	eel_register_binop(vm, "&", EEL_OP_BAND, 70, 0);
	eel_register_binop(vm, "|", EEL_OP_BOR, 60, 0);
	eel_register_binop(vm, "^", EEL_OP_BXOR, 60, 0);
	eel_register_binop(vm, "<<", EEL_OP_SHL, 55, 0);
	eel_register_binop(vm, ">>", EEL_OP_SHR, 55, 0);
	eel_register_binop(vm, "rol", EEL_OP_ROL, 55, 0);
	eel_register_binop(vm, "ror", EEL_OP_ROR, 55, 0);
	eel_register_binop(vm, "><", EEL_OP_BREV, 55, 0);

	/* Selectors */
	eel_register_binop(vm, "|<", EEL_OP_MIN, 50, 0);
	eel_register_binop(vm, ">|", EEL_OP_MAX, 50, 0);

	/* Comparisons */
	eel_register_binop(vm, "<", EEL_OP_LT, 40, EOPF_NOSHORT);
	eel_register_binop(vm, "<=", EEL_OP_LE, 40, EOPF_NOSHORT);
	eel_register_binop(vm, ">", EEL_OP_GT, 40, EOPF_NOSHORT);
	eel_register_binop(vm, ">=", EEL_OP_GE, 40, EOPF_NOSHORT);
	eel_register_binop(vm, "==", EEL_OP_EQ, 30, EOPF_NOSHORT);
	eel_register_binop(vm, "!=", EEL_OP_NE, 30, EOPF_NOSHORT);

	/* Boolean operators */
	eel_register_binop(vm, "and", EEL_OP_AND, 20, 0);
	eel_register_binop(vm, "or", EEL_OP_OR, 10, 0);
	eel_register_binop(vm, "xor", EEL_OP_XOR, 10, 0);

	/* Weak reference assignment */
	eel_register_binop(vm, "(=)", EEL_OP_WKASSN, 0, 0);

	/* Other operators */
	eel_register_binop(vm, "in", EEL_OP_IN, 110, 0);
#ifdef DEBUG
	for(i = 0; i < ESS_TOKENS; ++i)
		if(!es->tokentab[i])
		{
			eel_msg(es, EEL_EM_IERROR, "ESS token %d not defined!\n"
					"(ESS_FIRST_TK: %d, ESS_LAST_TK: %d, "
					"ESS_TOKENS: %d)\n", i, ESS_FIRST_TK,
					ESS_LAST_TK, ESS_TOKENS);
			es_close(es);
			return NULL;
		}
#endif
	eel_try(es)
		context_open(es);
	eel_except
	{
		eel_msg(es, EEL_EM_IERROR,
				"Could not open compiler start context!\n");
		es_close(es);
		return NULL;
	}

	eel_set_path(vm, NULL);	/* Set default path */

	/* Install system module */
	if(eel_system_init(vm, argc, argv))
	{
		eel_msg(es, EEL_EM_IERROR,
				"Could not initialize built-in system module!\n");
		es_close(es);
		return NULL;
	}

	/* Install io module */
	if(eel_io_init(vm))
	{
		eel_msg(es, EEL_EM_IERROR,
				"Could not initialize built-in io module!\n");
		es_close(es);
		return NULL;
	}


	/*
	 * Compile EEL built-in library
	 *
	 * NOTE: We need to inject 'io' and 'system' before 'eelbil' now, as
	 *       'eelbil' needs them for module loading!
	 */
	if(eel_builtin_init(vm))
	{
		eel_perror(vm, 1);
		eel_msg(es, EEL_EM_IERROR,
				"Could not initialize built-in library!\n");
		es_close(es);
		return NULL;
	}

	/* Install math module */
	if(eel_math_init(vm))
	{
		eel_msg(es, EEL_EM_IERROR,
				"Could not initialize built-in math module!\n");
		es_close(es);
		return NULL;
	}

	/* Install directory module */
	if(eel_dir_init(vm))
	{
		eel_msg(es, EEL_EM_IERROR, "Could not initialize built-in"
				" directory module!\n");
		es_close(es);
		return NULL;
	}

	/* Install DSP module */
	if(eel_dsp_init(vm))
	{
		eel_msg(es, EEL_EM_IERROR,
				"Could not initialize built-in DSP module!\n");
		es_close(es);
		return NULL;
	}

	return es->vm;
}