コード例 #1
0
ファイル: ocode.c プロジェクト: pcpa/owl
static void
eval_root(void)
{
    oast_t		*ast;
    oword_t		 offset;
    orecord_t		*record;
    ofunction_t		*function;

    assert(current_record == root_record);
    assert(current_function == root_record->function);
    oeval_ast(root_record->function->ast->c.ast);
    odata(root_record->function->ast->c.ast);

    for (offset = type_vector->offset - 1; offset > t_root; --offset) {
	record = type_vector->v.ptr[offset];
	if (otype(record) == t_prototype &&
	    likely(record->function && ofunction_p(record->function))) {
	    function = record->function;
	    current_record = record;
	    current_function = function;
	    /* Error later if function is actually called but never defined */
	    if ((ast = function->ast)) {
		oeval_ast(ast->l.ast);
		eval_ast_declexpr(ast->r.ast->r.ast);
		oeval_ast(ast->c.ast);
		odata(function->ast->c.ast);
	    }
	}
    }
    current_function = root_record->function;
    current_record = root_record;
}
コード例 #2
0
ファイル: otag.c プロジェクト: pcpa/owl
otag_t *
otag_object(oobject_t object)
{
    otag_t		*tag;
    otype_t		 type;
    orecord_t		*record;
    oobject_t		*pointer;

    if (object == null)
	return (null);
    switch (type = otype(object)) {
	case t_basic:
	    record = object;
	    if ((tag = (otag_t *)oget_hash(tag_table, record)) == null) {
		gc_ref(pointer);
		onew(pointer, tag);
		tag = *pointer;
		tag->name = record;
		tag->type = tag_basic;
		tag->size = record->length;
		oput_hash(tag_table, (oentry_t *)tag);
		gc_dec();
	    }
	    break;
	case t_record:		case t_namespace:
	    record = object;
	    if ((tag = (otag_t *)oget_hash(tag_table, record)) == null) {
		gc_ref(pointer);
		onew(pointer, tag);
		tag = *pointer;
		tag->name = record;
		tag->type = type == t_record ? tag_class : tag_namespace;
		tag->size = sizeof(oobject_t);
		oput_hash(tag_table, (oentry_t *)tag);
		gc_dec();
	    }
	    break;
	case t_tag:
	    tag = object;
	    break;
	case t_void ... t_mpc:
	    tag = types[type].tag;
	    break;
	default:
	    if (type & t_vector) {
		type &=  ~t_vector;
		if (type >= t_void && type < t_mpc)
		    tag = types[type].vtag;
		else
		    tag = vector_tag;
	    }
	    else
		tag = auto_tag;
	    break;
    }

    return (tag);

}
コード例 #3
0
ファイル: oeval.c プロジェクト: pcpa/owl
void
ocopy(oobject_t *pointer, oobject_t value)
{
    switch (otype(value)) {
	case t_word:
	    oget_word(pointer);		pointer = *pointer;
	    *(oword_t *)pointer = *(oword_t *)value;
	    break;
	case t_float:
	    oget_float(pointer);	pointer = *pointer;
	    *(ofloat_t *)pointer = *(ofloat_t *)value;
	    break;
	case t_rat:
	    oget_rat(pointer);		pointer = *pointer;
	    *(orat_t)pointer = *(orat_t)value;
	    break;
	case t_mpz:
	    oget_mpz(pointer);		pointer = *pointer;
	    mpz_set((ompz_t)pointer, (ompz_t)value);
	    break;
	case t_mpq:
	    oget_mpq(pointer);		pointer = *pointer;
	    mpq_set((ompq_t)pointer, (ompq_t)value);
	    break;
	case t_mpr:
	    oget_mpr(pointer);		pointer = *pointer;
	    mpfr_set((ompr_t)pointer, (ompr_t)value, thr_rnd);
	    break;
	case t_cdd:
	    oget_cdd(pointer);		pointer = *pointer;
	    *(ocdd_t *)pointer = *(ocdd_t *)value;
	    break;
	case t_cqq:
	    oget_cqq(pointer);		pointer = *pointer;
	    cqq_set((ocqq_t)pointer, (ocqq_t)value);
	    break;
	default:
	    assert(otype(value) == t_mpc);
	    oget_mpc(pointer);		pointer = *pointer;
	    mpc_set((ompc_t)pointer, (ompc_t)value, thr_rndc);
	    break;
    }
}
コード例 #4
0
ファイル: othread.c プロジェクト: pcpa/owl
static void
native_unlock(oobject_t list, oint32_t size)
{
    nat_mutex_t		*alist;

    alist = (nat_mutex_t *)list;
    if (alist->mutex == null || otype(alist->mutex) != t_mutex)
	othrow(except_invalid_argument);

    omutex_unlock(alist->mutex);
}
コード例 #5
0
ファイル: oeval.c プロジェクト: pcpa/owl
obool_t
ofalse_p(oobject_t object)
{
    if (object == null)
	return (true);
    switch (otype(object)) {
	case t_word:
	    return (*(oword_t *)object == 0);
	case t_float:
	    return (*(ofloat_t *)object == 0.0);
	case t_mpr:
	    return (mpfr_zero_p((ompr_t)object) != 0);
	default:
	    return (false);
    }
}
コード例 #6
0
ファイル: otag.c プロジェクト: pcpa/owl
otag_t *
otag_ast(otag_t *tag, oast_t **list)
{
    oast_t		*ast;
    oword_t		 length;

    if ((ast = *list) == null)
	return (tag);
    for (;;) {
	switch (ast->token) {
	    case tok_vector:
		/* This is the best place to "patch" the token value,
		 * so that other code will not confuse a vector
		 * declaration with a vector access. */
		ast->token = tok_vecdcl;
	    case tok_vecdcl:
		if (ast->r.ast) {
		    /* Handle constant expression */
		    if (ast->r.ast->token != tok_number)
			oeval_ast(ast->r.ast);
		    if (ast->r.ast->token != tok_number ||
			otype(ast->r.ast->l.value) != t_word)
			oparse_error(ast->r.ast,
				     "vector length not an integer");
		    if ((length = *(oword_t *)ast->r.ast->l.value) <= 0)
			oparse_error(ast->r.ast,
				     "invalid vector length");
		    tag = tag_vector_check(tag, length, ast->r.ast);
		}
		else
		    tag = otag_vector(tag, 0);
		if ((ast = ast->l.value) == null) {
		    *list = null;
		    return (tag);
		}
		break;
	    case tok_call:
	    case tok_symbol:
		*list = ast;
		return (tag);
	    case tok_ellipsis:
		return (varargs_tag);
	    default:
		oparse_error(ast, "expecting expression");
	}
    }
}
コード例 #7
0
ファイル: ocode.c プロジェクト: pcpa/owl
static void
eval_ast_renew(oast_t *ast)
{
    otag_t		*tag;

    oeval_ast(ast->l.ast);
    tag = oeval_ast_tag(ast->l.ast);
    if (tag == null || tag->type != tag_vector)
	oparse_error(ast->l.ast, "expecting vector %A", ast->l.ast);
    oeval_ast(ast->r.ast);
    if (ast->r.ast->token == tok_number) {
	if (ast->r.ast->l.value == null || otype(ast->r.ast->l.value) != t_word)
	    oparse_error(ast->r.ast, "expecting integer %A", ast->r.ast);
	if (*(oword_t *)ast->r.ast->l.value < 0)
	    oparse_error(ast->r.ast, "not a positive integer");
    }
}
コード例 #8
0
ファイル: oemit_except.c プロジェクト: pcpa/owl
static void
load_exception(jit_int32_t regval, oword_t offset)
{
    if (otype(current_record) == t_namespace) {
	if (GPR[GLOBAL] != JIT_NOREG)
	    jit_addi(regval, GPR[GLOBAL], offset);
	else
	    jit_movi(regval, (oword_t)gd + offset);
    }
    else {
	if (GPR[FRAME] != JIT_NOREG)
	    jit_addi(regval, GPR[FRAME], offset);
	else {
	    jit_ldxi(regval, JIT_V0, offsetof(othread_t, fp));
	    jit_addi(regval, regval, offset);
	}
    }
}
コード例 #9
0
ファイル: othread.c プロジェクト: pcpa/owl
static void
native_join(oobject_t list, oint32_t ac)
{
    GET_THREAD_SELF()
    nat_join_t		*alist;

    alist = (nat_join_t *)list;
    if (alist->thread == null || otype(alist->thread) != t_thread)
	othrow(except_invalid_argument);
    if (pthread_equal(thread_self->pthread, alist->thread->pthread))
	othrow(except_invalid_argument);

    /* Do not fail if attempting to join a thread no longer running.
     * The thread return value, if any is gc protected by the fact
     * there is at least one reference to it. */
    pthread_join(alist->thread->pthread, null);

    ovm_move(&thread_self->r0, &alist->thread->r0);
}
コード例 #10
0
ファイル: oeval.c プロジェクト: pcpa/owl
static void
eval_setup(oregister_t *r, oobject_t v)
{
    if (v == null) {
	r->t = t_void;
	r->v.o = null;
    }
    else {
	switch (r->t = otype(v)) {
	    case t_word:
		r->v.w = *(oword_t *)v;
		break;
	    case t_float:
		r->v.d = *(ofloat_t *)v;
		break;
	    case t_rat:
		r->v.r = *(orat_t)v;
		break;
	    case t_mpz:
		mpz_set(ozr(r), (ompz_t)v);
		break;
	    case t_mpq:
		mpq_set(oqr(r), (ompq_t)v);
		break;
	    case t_mpr:
		mpfr_set(orr(r), (ompr_t)v, thr_rnd);
		break;
	    case t_cdd:
		r->v.dd = *(ocdd_t *)v;
		break;
	    case t_cqq:
		cqq_set(oqq(r), (ocqq_t)v);
		break;
	    default:
		assert(r->t == t_mpc);
		mpc_set(occ(r), (ompc_t)v, thr_rndc);
		break;
	}
    }
}
コード例 #11
0
ファイル: otag.c プロジェクト: pcpa/owl
static otag_t *
tag_ast_data_vector(otag_t *tag, oast_t *ast)
{
    oast_t		*rast;
    otag_t		*btag;
    otag_t		*rtag;
    oword_t		 length;
    oword_t		 offset;

    btag = tag->base;
    for (offset = length = 0; ast; ast = ast->next, offset++) {
	if (ast->token == tok_init) {
	    rast = ast->l.ast;
	    if (rast->token != tok_number || otype(rast->l.value) != t_word)
		oparse_error(rast, "not an integer");
	    offset = *(oword_t *)rast->l.value;
	    if (offset < 0)
		oparse_error(rast, "negative offset");
	    if (tag->size && tag->size <= offset)
		oparse_error(rast, "offset out of bounds");
	    rtag = otag_ast_data(tag->base, ast->r.value);
	}
	else {
	    rtag = otag_ast_data(tag->base, ast);
	    if (tag->size && tag->size <= offset)
		oparse_error(ast, "too many initializers");
	}
	if (rtag->type == btag->type && rtag->size > btag->size)
	    btag = rtag;
	if (length <= offset)
	    length = offset + 1;
    }
    if (!tag->size)
	tag = tag_vector_check(btag, length, ast);

    return (tag);
}
コード例 #12
0
ファイル: readobj.c プロジェクト: NREL/Radiance
void
getobject(				/* read the next object */
	char  *name,
	FILE  *fp
)
{
#define	OALIAS	-2
	OBJECT  obj;
	char  sbuf[MAXSTR];
	int  rval;
	OBJREC  *objp;

	if ((obj = newobject()) == OVOID)
		error(SYSTEM, "out of object space");
	objp = objptr(obj);
					/* get modifier */
	strcpy(sbuf, "EOF");
	fgetword(sbuf, MAXSTR, fp);
	if (strchr(sbuf, '\t')) {
		sprintf(errmsg, "(%s): illegal tab in modifier \"%s\"",
					name, sbuf);
		error(USER, errmsg);
	}
	if (!strcmp(sbuf, VOIDID))
		objp->omod = OVOID;
	else if (!strcmp(sbuf, ALIASMOD))
		objp->omod = OALIAS;
	else if ((objp->omod = modifier(sbuf)) == OVOID) {
		sprintf(errmsg, "(%s): undefined modifier \"%s\"", name, sbuf);
		error(USER, errmsg);
	}
					/* get type */
	strcpy(sbuf, "EOF");
	fgetword(sbuf, MAXSTR, fp);
	if ((objp->otype = otype(sbuf)) < 0) {
		sprintf(errmsg, "(%s): unknown type \"%s\"", name, sbuf);
		error(USER, errmsg);
	}
					/* get identifier */
	sbuf[0] = '\0';
	fgetword(sbuf, MAXSTR, fp);
	if (strchr(sbuf, '\t')) {
		sprintf(errmsg, "(%s): illegal tab in identifier \"%s\"",
					name, sbuf);
		error(USER, errmsg);
	}
	objp->oname = savqstr(sbuf);
					/* get arguments */
	if (objp->otype == MOD_ALIAS) {
		OBJECT  alias;
		strcpy(sbuf, "EOF");
		fgetword(sbuf, MAXSTR, fp);
		if ((alias = modifier(sbuf)) == OVOID) {
			sprintf(errmsg, "(%s): bad reference \"%s\"",
					name, sbuf);
			objerror(objp, USER, errmsg);
		}
		if (objp->omod == OALIAS || 
				objp->omod == objptr(alias)->omod) {
			objp->omod = alias;
		} else {
			objp->oargs.sarg = (char **)malloc(sizeof(char *));
			if (objp->oargs.sarg == NULL)
				error(SYSTEM, "out of memory in getobject");
			objp->oargs.nsargs = 1;
			objp->oargs.sarg[0] = savestr(sbuf);
		}
	} else if ((rval = readfargs(&objp->oargs, fp)) == 0) {
		sprintf(errmsg, "(%s): bad arguments", name);
		objerror(objp, USER, errmsg);
	} else if (rval < 0) {
		sprintf(errmsg, "(%s): error reading scene", name);
		error(SYSTEM, errmsg);
	}
	if (objp->omod == OALIAS) {
		sprintf(errmsg, "(%s): inappropriate use of '%s' modifier",
				name, ALIASMOD);
		objerror(objp, USER, errmsg);
	}
					/* initialize */
	objp->os = NULL;

	insertobject(obj);		/* add to global structure */
#undef OALIAS
}
コード例 #13
0
ファイル: oeval.c プロジェクト: pcpa/owl
void
ocoerce(oobject_t *pointer, otype_t type, oobject_t value)
{
    union {
	oint64_t	 i;
	ofloat32_t	 f;
	ofloat_t	 d;
    } data;

    switch (type) {
	case t_int8:		case t_uint8:
	case t_int16:		case t_uint16:
	case t_int32:		case t_uint32:
	case t_int64:		case t_uint64:
	    switch (otype(value)) {
		case t_word:
		    data.i = *(oword_t *)value;
		    break;
		case t_float:
		    data.i = *(ofloat_t *)value;
		    break;
		case t_mpz:
		    data.i = ompz_get_sl((ompz_t)value);
		    break;
		case t_mpq:
		    data.i = ompq_get_sl((ompq_t)value);
		    break;
		case t_mpr:
		    data.i = ompr_get_sl((ompr_t)value);
		    break;
		case t_cdd:
		    data.i = real(*(ocdd_t *)value);
		    break;
		case t_cqq:
		    data.i = ompq_get_sl(cqq_realref((ocqq_t)value));
		    break;
		default:
		    assert(otype(value) == t_mpc);
		    data.i = ompr_get_sl(mpc_realref((ompc_t)value));
		    break;
	    }
	    break;
	case t_float32:		case t_float64:
	    switch (otype(value)) {
		case t_word:
		    data.d = *(oword_t *)value;
		    break;
		case t_float:
		    data.d = *(ofloat_t *)value;
		    break;
		case t_mpz:
		    data.d = mpz_get_d((ompz_t)value);
		    break;
		case t_mpq:
		    data.d = mpq_get_d((ompq_t)value);
		    break;
		case t_mpr:
		    data.d = mpfr_get_d((ompr_t)value, thr_rnd);
		    break;
		case t_cdd:
		    data.d = real(*(ocdd_t *)value);
		    break;
		case t_cqq:
		    data.d = mpq_get_d(cqq_realref((ocqq_t)value));
		    break;
		default:
		    assert(otype(value) == t_mpc);
		    data.i = mpfr_get_d(mpc_realref((ompc_t)value), thr_rnd);
		    break;
	    }
	    break;
	default:
	    data.i = 0;
	    break;
    }

    switch (type) {
	case t_int8:
	    oget_word(pointer);		pointer = *pointer;
	    *(oword_t *)pointer = (oint8_t)data.i;
	    break;
	case t_uint8:
	    oget_word(pointer);		pointer = *pointer;
	    *(oword_t *)pointer = (ouint8_t)data.i;
	    break;
	case t_int16:
	    oget_word(pointer);		pointer = *pointer;
	    *(oword_t *)pointer = (oint16_t)data.i;
	    break;
	case t_uint16:
	    oget_word(pointer);		pointer = *pointer;
	    *(oword_t *)pointer = (ouint16_t)data.i;
	    break;
	case t_int32:
	    oget_word(pointer);		pointer = *pointer;
	    *(oword_t *)pointer = (oint32_t)data.i;
	    break;
	case t_uint32:
#if __WORDSIZE == 32
	    if ((ouword_t)data.i != data.i) {
		oget_mpz(pointer);	pointer = *pointer;
		mpz_set_ui((ompz_t)pointer, (ouword_t)data.i);
	    }
	    else
#endif
	    {
		oget_word(pointer);	pointer = *pointer;
		*(oword_t *)pointer = (ouint32_t)data.i;
	    }
	    break;
	case t_int64:
#if __WORDSIZE == 32
	    if ((oword_t)data.i != data.i) {
		oget_mpz(pointer);	pointer = *pointer;
		ompz_set_sl((ompz_t)pointer, data.i);
	    }
	    else
#endif
	    {
		oget_word(pointer);	pointer = *pointer;
		*(oword_t *)pointer = (oword_t)data.i;
	    }
	    break;
	case t_uint64:
	    if ((ouword_t)data.i != data.i) {
		oget_mpz(pointer);	pointer = *pointer;
		mpz_set_ui((ompz_t)pointer, (ouword_t)data.i);
	    }
	    else {
		oget_word(pointer);	pointer = *pointer;
		*(oword_t *)pointer = (ouword_t)data.i;
	    }
	    break;
	case t_float32:
	    data.f = data.d;
	    data.d = data.f;
	case t_float:
	    oget_float(pointer);	pointer = *pointer;
	    *(ofloat_t *)pointer = data.d;
	    break;
	default:
	    ocopy(pointer, value);
	    break;
    }
}
コード例 #14
0
ファイル: wsgi.cpp プロジェクト: AndreLouisCaron/cxxpy
int main ( int, char ** )
try
{
    // Prepare the interpreter.a
    const py::Library library;

    // Build input stream class for 'wsgi.input' object.
    py::TypeBuilder itype("istream");
    itype.init(py::ctor<&exports::init>());
    itype.add(py::Method("read", py::vararg<&exports::read>()));
    itype.add(py::Method("readline", py::noargs<&exports::readline>()));
    itype.add(py::Method("readlines", py::vararg<&exports::readlines>()));
    itype.iterable(py::noargs<&exports::iter>(),
                  py::noargs<&exports::next>());
    itype.finish();

    // Have 'wsgi.input' object read from standard input stream.
    py::Object istream = itype();
    py::TypeBuilder::set_baton
        (istream, static_cast<std::istream*>(&std::cin));

    // Build output stream class for 'wsgi.errors' object.
    py::TypeBuilder otype("ostream");
    otype.init(py::ctor<&exports::init>());
    otype.add(py::Method("flush", py::noargs<&exports::flush>()));
    otype.add(py::Method("write", py::vararg<&exports::write>()));
    otype.add(py::Method("writelines", py::vararg<&exports::writelines>()));
    otype.finish();

    // Have 'wsgi.errors' object write to standard output stream.
    py::Object ostream = otype();
    py::TypeBuilder::set_baton
        (ostream, static_cast<std::ostream*>(&std::cout));

    // WSGI bootstrap code.
    wsgi::Runner execute("wsgi-bootstrap.py");
    // WSGI application handler.
    wsgi::Application application("sample", "wsgi-application.py");

    // Prepare application execution context.
    py::Map environment;
    // Required CGI-style variables.
    environment.put("REQUEST_METHOD", "GET");  // "GET", "POST", ...
#if 0
    environment.put("SCRIPT_NAME", "");     // Path to application script.
    environment.put("PATH_INFO", "");       // URL delegated to application.
    environment.put("QUERY_STRING", "");    // URL query string.
    environment.put("SERVER_NAME", "");     //
    environment.put("SERVER_PORT", "");     //
    environment.put("SERVER_PROTOCOL", ""); // "HTTP/1.x"
    // Optional CGI-style variables.
    environment.put("CONTENT_TYPE", "");
    environment.put("CONTENT_LENGTH", "");
#endif
#if 0
    // HTTP headers.
    environment.put("HTTP_HOST", "");
    //environment.put(...);
#endif
    // WSGI variables.
    py::Tuple version(2);
    version[0] = py::Int(1);
    version[1] = py::Int(0);
    environment.put("wsgi.version", version);
    environment.put("wsgi.url_scheme", "http");
    environment.put("wsgi.input", istream);
    environment.put("wsgi.errors", ostream);
    environment.put("wsgi.multithread", py::False());
    environment.put("wsgi.multiprocess", py::False());
    environment.put("wsgi.run_once", py::True());

    // Execute application and print HTTP response to "cout".
    wsgi::http_response(execute(application, environment),
                        wsgi::ostream_handler(std::cout));
}
catch ( const py::SystemError& error )
{
    std::cerr
        << "Error: '" << error.message() << "'."
        << std::endl;
    return (EXIT_FAILURE);
}
catch ( const py::Error& )
{
    std::cerr
        << "Error: 'some python error'."
        << std::endl;
    return (EXIT_FAILURE);
}
catch ( const std::exception& error )
{
    std::cerr
        << "Error: '" << error.what() << "'."
        << std::endl;
    return (EXIT_FAILURE);
}
コード例 #15
0
ファイル: ocode.c プロジェクト: pcpa/owl
void
oeval_ast(oast_t *ast)
{
    oast_t		*temp;
    orecord_t		*record;
    osymbol_t		*symbol;

    switch (ast->token) {
	case tok_set:		case tok_andset:
	case tok_orset:		case tok_xorset:
	case tok_mul2set:	case tok_div2set:
	case tok_shlset:	case tok_shrset:
	case tok_addset:	case tok_subset:
	case tok_mulset:	case tok_divset:
	case tok_trunc2set:	case tok_remset:
	    oeval_ast(ast->l.ast);
	    oeval_ast(ast->r.ast);
	    break;
	case tok_vector:
	    oeval_ast(ast->l.ast);
	    if (ast->r.ast == null)
		oparse_error(ast, "expecting offset");
	    oeval_ast(ast->r.ast);
	    /* validate element reference */
	    oeval_ast_tag(ast);
	    break;
	case tok_dot:
	    oeval_ast(ast->l.ast);
	    /* validate field reference */
	    oeval_ast_tag(ast);
	    break;
	case tok_explicit:
	    oeval_ast_tag(ast);
	    break;
	case tok_andand:	case tok_oror:
	case tok_ne:		case tok_lt:
	case tok_le:		case tok_eq:
	case tok_ge:		case tok_gt:
	case tok_and:		case tok_or:
	case tok_xor:		case tok_mul2:
	case tok_div2:		case tok_shl:
	case tok_shr:		case tok_add:
	case tok_sub:		case tok_mul:
	case tok_div:		case tok_trunc2:
	case tok_rem:		case tok_complex:
	    oeval_ast(ast->l.ast);
	    oeval_ast(ast->r.ast);
	    ofold(ast);
	    break;
	case tok_inc:		case tok_dec:
	case tok_postinc:	case tok_postdec:
	case tok_new:		case tok_thread:
	    oeval_ast(ast->l.ast);
	    break;
	case tok_init:		case tok_vecnew:
	    oeval_ast(ast->r.ast);
	    break;
	case tok_com:		case tok_plus:
	case tok_neg:		case tok_not:
	case tok_integer_p:	case tok_rational_p:
	case tok_float_p:	case tok_real_p:
	case tok_complex_p:	case tok_number_p:
	case tok_finite_p:	case tok_inf_p:
	case tok_nan_p:		case tok_num:
	case tok_den:		case tok_real:
	case tok_imag:		case tok_signbit:
	case tok_abs:		case tok_signum:
	case tok_rational:	case tok_arg:
	case tok_conj:		case tok_floor:
	case tok_trunc:		case tok_round:
	case tok_ceil:		case tok_sqrt:
	case tok_cbrt:		case tok_sin:
	case tok_cos:		case tok_tan:
	case tok_asin:		case tok_acos:
	case tok_atan:		case tok_sinh:
	case tok_cosh:		case tok_tanh:
	case tok_asinh:		case tok_acosh:
	case tok_atanh:		case tok_proj:
	case tok_exp:		case tok_log:
	case tok_log2:		case tok_log10:
	    oeval_ast(ast->l.ast);
	    ofold(ast);
	    break;
	case tok_atan2:		case tok_pow:
	case tok_hypot:
	    oeval_ast(ast->l.ast);
	    oeval_ast(ast->r.ast);
	    ofold(ast);
	    break;
	case tok_subtypeof:
	    oeval_ast(ast->l.ast);
	    oeval_ast(ast->r.ast);
	    break;
	case tok_sizeof:
	    eval_ast_sizeof(ast);
	    break;
	case tok_typeof:
	    eval_ast_typeof(ast);
	    break;
	case tok_renew:
	    eval_ast_renew(ast);
	    break;
	case tok_question:
	    oeval_ast(ast->t.ast);
	    oeval_ast(ast->l.ast);
	    oeval_ast(ast->r.ast);
	    break;
	case tok_if:
	    eval_ast_stat(ast->t.ast);
	    eval_ast_stat(ast->l.ast);
	    eval_ast_stat(ast->r.ast);
	    break;
	case tok_return:
	    check_exception(ast);
	case tok_throw:
	    if (ast->l.ast)
		oeval_ast(ast->l.ast);
	    break;
	case tok_switch:
	    eval_ast_stat(ast->t.ast);
	    eval_ast_stat(ast->c.ast);
	    break;
	case tok_for:
	    eval_ast_stat(ast->l.ast);
	    eval_ast_stat(ast->t.ast);
	    eval_ast_stat(ast->r.ast);
	    eval_ast_stat(ast->c.ast);
	    break;
	case tok_do:		case tok_while:
	    eval_ast_stat(ast->c.ast);
	    eval_ast_stat(ast->t.ast);
	    break;
	case tok_list:
	    temp = ast->l.ast;
	    eval_ast_stat(temp);
	    /*   Check inner fields for the sake of clean debug output. */
	    if (temp->next == null && temp->r.value == null &&
		temp->t.value == null && temp->c.value == null)
		omove_ast_up_full(ast, temp);
	    break;
	case tok_call:
	    if (ast->l.ast->token != tok_symbol)
		oeval_ast(ast->l.ast);
	    else
		update_symbol(ast->l.ast, true);
	    eval_ast_stat(ast->r.ast);
	    break;
	case tok_stat:		case tok_code:
	case tok_data:		case tok_finally:
	    eval_ast_stat(ast->l.ast);
	    break;
	case tok_decl:
	    oeval_ast(ast->l.ast);
	    eval_ast_decl(ast->r.ast);
	    break;
	case tok_symbol:
	    update_symbol(ast, false);
	    break;
	case tok_goto:
	    eval_ast_goto(ast);
	    break;
	case tok_try:
	    eval_ast_stat(ast->r.ast);
	    break;
	case tok_catch:
	    eval_ast_decl(ast->l.ast->r.ast);
	    eval_ast_stat(ast->r.ast);
	    break;
	case tok_break:		case tok_continue:
	    check_exception(ast);
	case tok_type:		case tok_number:	case tok_string:
	case tok_class:		case tok_label:		case tok_case:
	case tok_default:	case tok_function:	case tok_ellipsis:
	case tok_this:		case tok_enum:
	    break;
	case tok_namespace:
	    record = current_record;
	    assert(ast->l.ast->token == tok_symbol);
	    symbol = ast->l.ast->l.value;
	    current_record = symbol->value;
	    assert(otype(current_record) == t_namespace);
	    eval_ast_stat(ast->c.ast);
	    current_record = record;
	    break;
	default:
#if DEBUG
	    oparse_warn(ast,
			"code: not handling %s", otoken_to_charp(ast->token));
#endif
	    break;
    }
}
コード例 #16
0
ファイル: ocode.c プロジェクト: pcpa/owl
otag_t *
oeval_ast_tag(oast_t *ast)
{
    otag_t		*tag;
    oast_t		*rast;
    orecord_t		*record;
    osymbol_t		*symbol;
    ovector_t		*vector;

    switch (ast->token) {
	case tok_symbol:
	    update_symbol(ast, false);
	    symbol = ast->l.value;
	    return (symbol->tag);
	case tok_vector:
	    tag = oeval_ast_tag(ast->l.ast);
	    switch (tag->type) {
		case tag_vector:
		case tag_varargs:
		    break;
		case tag_hash:
		    /* Patch token to simplify later parsing */
		    ast->token = tok_hash;
		    break;
		default:
		    if (ast->l.ast->token == tok_symbol) {
			symbol = ast->l.ast->l.value;
			oparse_error(ast, "'%p' is not a vector %A",
				     symbol->name, ast);
		    }
		    oparse_error(ast, "not a vector reference %A", ast);
		    break;
	    }
	    return (tag->base);
	case tok_dot:
	    if (ast->l.ast->token == tok_this) {
		for (record = current_record; record; record = record->parent)
		    if (otype(record) == t_record)
			break;
		if (record == null)
		    oparse_error(ast,
				 "'this' now allowed outside 'class' method");
		tag = record->name->tag;
	    }
	    else
		tag = oeval_ast_tag(ast->l.ast);
	    rast = ast->r.ast;
	    assert(rast->token == tok_symbol);
	    if (tag->type == tag_class && ast->l.ast->token == tok_this) {
		omove_ast_up_full(ast, rast);
		rast = ast;
	    }
	    else {
		while (tag->type == tag_function) {
		    vector = tag->name;
		    tag = vector->v.ptr[0];
		}
		if (tag->type != tag_class) {
		    if (ast->l.ast->token == tok_symbol) {
			symbol = ast->l.ast->l.value;
			oparse_error(ast, "'%p' is not a class or namespace %A",
				     symbol->name, ast);
		    }
		    oparse_error(ast, "not a class or namespace %A", ast);
		}
	    }
	    record = tag->name;
	    symbol = rast->l.value;
	    vector = symbol->name;
	    if ((symbol = oget_symbol(record, vector)) == null)
		oparse_error(ast, "'%p' has no %s named '%p'",
			     record->name,
			     tag->type == tag_class ? "field" : "symbol",
			     vector);
	    rast->l.value = symbol;
	    return (symbol->tag);
	case tok_explicit:
	    tag = ast->l.ast->l.value;
	    if (tag->type != tag_class)
		oparse_error(ast, "not a class reference");
	    record = tag->name;
	    rast = ast->r.ast;
	    assert(rast->token == tok_symbol);
	    symbol = rast->l.value;
	    vector = symbol->name;
	    if ((symbol = oget_symbol(record, vector)) == null)
		oparse_error(ast, "'%p' has no field named '%p'",
			     record->name, vector);
	    rast->l.value = symbol;
	    return (symbol->tag);
	case tok_string:
	    return (string_tag);
	case tok_ellipsis:
	    return (varargs_tag);
	case tok_call:
	    return (oeval_ast_tag(ast->l.ast));
	default:
	    oparse_error(ast, "not a type or symbol reference %A", ast);
    }
}
コード例 #17
0
ファイル: ocode.c プロジェクト: pcpa/owl
static void
eval_ast_typeof(oast_t *ast)
{
    otype_t		 type;
    osymbol_t		*symbol;
    ofunction_t		*function;

    oeval_ast(ast->l.ast);
    switch (ast->l.ast->token) {
	case tok_number:
	    type = otype(ast->l.ast->l.value);
	    break;
	case tok_string:
	    type = t_string;
	    break;
	case tok_symbol:
	    symbol = ast->l.ast->l.value;
	    type = otag_to_type(symbol->tag);
	    break;
	case tok_call:
	    symbol = ast_call_symbol(ast->l.ast);
	    function = symbol->value;
	    type = otag_to_type(function->tag) & ~t_function;
	    break;
	case tok_type:
	    type = otag_to_type(ast->l.ast->l.value);
	    break;
	default:
	    return;
    }

    /* Return "normalized" type, not variable type, because
     * otherwise there would be inconsistencies with actual
     * runtime type information for "unsigned word" if it
     * does not fit in a "signed word", as well as being
     * simply tagged as "word" if moved to a vm register */
    switch ((oword_t)type) {
	case t_undef:
	    if (ast->l.ast->token != tok_type)
		return;
	    type = t_void;
	    break;
	case t_void:
	    break;
	case t_int8:			case t_uint8:
	case t_int16:			case t_uint16:
	case t_int32:
#if __WORDSIZE == 64
	case t_uint32:			case t_int64:
#endif
	    type = t_word;
	    break;
#if __WORDSIZE == 32
	case t_uint32:			case t_int64:
#endif
	case t_uint64:
	    if (ast->l.ast->token != tok_type)
		return;
	    type = t_word;
	    break;
	case t_float32:			case t_float64:
	    break;
	case t_vector|t_int8:		case t_vector|t_uint8:
	case t_vector|t_int16:		case t_vector|t_uint16:
	case t_vector|t_int32:		case t_vector|t_uint32:
	case t_vector|t_int64:		case t_vector|t_uint64:
	case t_vector|t_float32:	case t_vector|t_float64:
	    break;
	case t_vector|t_undef:
	    type = t_vector;
	    break;
	default:
	    if (type > rtti_vector->offset)
		return;
	    break;
    }
    odel_object(&ast->l.value);
    ast->token = tok_number;
    onew_word(&ast->l.value, type);
}