export PKG_CONFIG_PATH="$PHP_PSI_LIBFFI/lib/pkgconfig:$PHP_PSI_LIBJIT/lib/pkgconfig:$PKG_CONFIG_PATH"
])
+AC_DEFUN(PSI_CHECK_SIZEOF, [
+ AC_CHECK_SIZEOF($1, [], $2)
+ if test "$AS_TR_SH([ac_cv_sizeof_]$1)"; then
+ add_int_const "AS_TR_CPP([SIZEOF_]$1)" "$AS_TR_SH([ac_cv_sizeof_]$1)"
+ fi
+])
+
AC_DEFUN(PSI_CHECK_OFFSETOF, [
_AC_CACHE_CHECK_INT(
[offset of $2 in $1],
AC_DEFUN(PSI_STRUCT_MEMBER, [
m4_define([member_name], PSI_VAR_NAME($2))
m4_define([member_type], PSI_VAR_TYPE($2))
- AC_CHECK_SIZEOF(AS_TR_SH($1)[_]member_name, [], PSI_INCLUDES
+ PSI_CHECK_SIZEOF(AS_TR_SH($1)[_]member_name, PSI_INCLUDES
[#define ]AS_TR_SH($1)[_]member_name (($1 *)0)->member_name
)
if test -n "$AS_TR_SH([ac_cv_sizeof_$1][_]member_name)" \
])
AC_DEFUN(PSI_STRUCT, [
- AC_CHECK_SIZEOF($1, [], PSI_INCLUDES)
+ PSI_CHECK_SIZEOF($1, PSI_INCLUDES)
psi_struct_name=m4_bregexp([$1], [^\(struct \)?\(\w+\)], [\2])
psi_struct_members="{PSI_T_STRUCT, \"struct\", \"$psi_struct_name\", 0, $AS_TR_SH([ac_cv_sizeof_]$1), 0, 0}"
ifelse([$2],,,[m4_map_args_sep([PSI_STRUCT_MEMBER($1, m4_normalize(], [))], [], $2)])
dnl PSI_TYPE(type name, basic type, includes)
AC_DEFUN(PSI_TYPE, [
ifdef(AS_TR_CPP(AC_TYPE_$1), AS_TR_CPP(AC_TYPE_$1))
- AC_CHECK_SIZEOF($1, [], PSI_INCLUDES)
+ PSI_CHECK_SIZEOF($1, PSI_INCLUDES)
psi_basic_type=$2
case $psi_basic_type in
int)
AC_CHECK_HEADERS(stdint.h)
AC_TYPE_INT8_T
- AC_CHECK_SIZEOF(int8_t)
+ PSI_CHECK_SIZEOF(int8_t)
AC_CHECK_ALIGNOF(int8_t)
AC_TYPE_UINT8_T
- AC_CHECK_SIZEOF(uint8_t)
+ PSI_CHECK_SIZEOF(uint8_t)
AC_CHECK_ALIGNOF(uint8_t)
AC_TYPE_INT16_T
- AC_CHECK_SIZEOF(int16_t)
+ PSI_CHECK_SIZEOF(int16_t)
AC_CHECK_ALIGNOF(int16_t)
AC_TYPE_UINT16_T
- AC_CHECK_SIZEOF(uint16_t)
+ PSI_CHECK_SIZEOF(uint16_t)
AC_CHECK_ALIGNOF(uint16_t)
AC_TYPE_INT32_T
- AC_CHECK_SIZEOF(int32_t)
+ PSI_CHECK_SIZEOF(int32_t)
AC_CHECK_ALIGNOF(int32_t)
AC_TYPE_UINT32_T
- AC_CHECK_SIZEOF(uint32_t)
+ PSI_CHECK_SIZEOF(uint32_t)
AC_CHECK_ALIGNOF(uint32_t)
AC_TYPE_INT64_T
- AC_CHECK_SIZEOF(int64_t)
+ PSI_CHECK_SIZEOF(int64_t)
AC_CHECK_ALIGNOF(int64_t)
AC_TYPE_UINT64_T
- AC_CHECK_SIZEOF(uint64_t)
+ PSI_CHECK_SIZEOF(uint64_t)
AC_CHECK_ALIGNOF(uint64_t)
PSI_TYPE(float)
PSI_DECL(int timer_delete, [(timer_t t)])
PSI_DECL(int timer_getoverrun, [(timer_t t)])
PSI_DECL(int timer_gettime, [(timer_t t, struct itimerspec *ts)])
- PSI_DECL(int timer_settime, [(timer_t t, struct itimerspec *value, struct itimerspec *ovalue)])
+ PSI_DECL(int timer_settime, [(timer_t t, int flags, struct itimerspec *value, struct itimerspec *ovalue)])
PSI_DECL(void tzset, [()])
])
return (set && *set && '0' != *set);
}
+typedef struct psi_object {
+ void *data;
+ size_t size;
+ zend_object std;
+} psi_object;
+
+static inline psi_object *PSI_OBJ(zval *zv, zend_object *zo) {
+ if (zv) {
+ zo = Z_OBJ_P(zv);
+ }
+ return (void *) (((char *) zo) - zo->handlers->offset);
+}
+
size_t psi_t_alignment(token_t t);
size_t psi_t_size(token_t t);
size_t psi_t_align(token_t t, size_t s);
zend_internal_arg_info *psi_internal_arginfo(impl *impl);
size_t psi_num_min_args(impl *impl);
+void psi_to_void(zval *return_value, set_value *set, impl_val *ret_val);
void psi_to_bool(zval *return_value, set_value *set, impl_val *ret_val);
void psi_to_int(zval *return_value, set_value *set, impl_val *ret_val);
void psi_to_double(zval *return_value, set_value *set, impl_val *ret_val);
void psi_to_string(zval *return_value, set_value *set, impl_val *ret_val);
void psi_to_array(zval *return_value, set_value *set, impl_val *ret_val);
+void psi_to_object(zval *return_value, set_value *set, impl_val *ret_val);
void psi_call(zend_execute_data *execute_data, zval *return_value, impl *impl);
case PSI_T_TO_ARRAY:
set->func->handler = psi_to_array;
break;
+ case PSI_T_TO_OBJECT:
+ set->func->handler = psi_to_object;
+ break;
+ case PSI_T_VOID:
+ set->func->handler = psi_to_void;
+ break;
EMPTY_SWITCH_DEFAULT_CASE();
}
void PSI_ContextCall(PSI_Context *C, impl_val *ret_val, decl *decl)
{
+ errno = 0;
C->ops->call(C, ret_val, decl);
}
#include "php.h"
#include "php_ini.h"
#include "ext/standard/info.h"
+#include "zend_exceptions.h"
#include "php_psi.h"
#include "parser.h"
STD_PHP_INI_ENTRY("psi.directory", "psi.d", PHP_INI_SYSTEM, OnUpdateString, directory, zend_psi_globals, psi_globals)
PHP_INI_END();
+static zend_object_handlers psi_object_handlers;
+static zend_class_entry *psi_class_entry;
+
void psi_error(int type, const char *msg, ...)
{
char buf[0x1000];
return n;
}
+void psi_to_void(zval *return_value, set_value *set, impl_val *ret_val)
+{
+ RETVAL_NULL();
+}
+
void psi_to_bool(zval *return_value, set_value *set, impl_val *ret_val)
{
psi_to_int(return_value, set, ret_val);
token_t t = real_decl_type(var->arg->type)->type;
switch (t) {
+ case PSI_T_VOID:
case PSI_T_INT8:
case PSI_T_UINT8:
if (!var->arg->var->pointer_level) {
} else {
ZEND_ASSERT(0);
}
+}
+void psi_to_object(zval *return_value, set_value *set, impl_val *r_val)
+{
+ decl_var *var = set->vars->vars[0];
+ impl_val *ret_val = deref_impl_val(r_val, var);
+ psi_object *obj;
+
+ if (ret_val->ptr) {
+ object_init_ex(return_value, psi_class_entry);
+ obj = PSI_OBJ(return_value, NULL);
+ obj->data = ret_val->ptr;
+ } else {
+ RETVAL_NULL();
+ }
}
static inline ZEND_RESULT_CODE psi_parse_args(zend_execute_data *execute_data, impl *impl)
{
impl_arg *iarg;
+ zend_error_handling zeh;
+
+ zend_replace_error_handling(EH_THROW, zend_exception_get_default(), &zeh);
if (!impl->func->args->count) {
- return zend_parse_parameters_none();
+ ZEND_RESULT_CODE rv;
+
+ rv = zend_parse_parameters_none();
+ zend_restore_error_handling(&zeh);
+ return rv;
}
ZEND_PARSE_PARAMETERS_START(psi_num_min_args(impl), impl->func->args->count)
}
} else if (PSI_T_ARRAY == iarg->type->type) {
/* handled as _zv in let or set */
- Z_PARAM_PROLOGUE(0);
+ Z_PARAM_ARRAY_EX(iarg->_zv, 1, 0);
+ } else if (PSI_T_OBJECT == iarg->type->type) {
+ Z_PARAM_OBJECT_EX(iarg->_zv, 1, 0);
} else {
error_code = ZPP_ERROR_FAILURE;
break;
if (_i < _max_num_args) {
goto nextarg;
}
- ZEND_PARSE_PARAMETERS_END_EX(return FAILURE);
+ ZEND_PARSE_PARAMETERS_END_EX(
+ zend_restore_error_handling(&zeh);
+ return FAILURE
+ );
+ zend_restore_error_handling(&zeh);
return SUCCESS;
}
arg_val->lval = zval_get_long(iarg->_zv);
}
break;
+ case PSI_T_PATHVAL:
case PSI_T_STRVAL:
if (iarg->type->type == PSI_T_STRING) {
arg_val->ptr = estrdup(iarg->val.zend.str->val);
darg->let->mem = arg_val->ptr;
zend_string_release(zs);
}
+ if (PSI_T_PATHVAL == darg->let->val->func->type) {
+ if (SUCCESS != php_check_open_basedir(arg_val->ptr)) {
+ efree(arg_val->ptr);
+ return NULL;
+ }
+ }
break;
case PSI_T_STRLEN:
if (iarg->type->type == PSI_T_STRING) {
}
}
break;
+ case PSI_T_OBJVAL:
+ if (iarg->type->type == PSI_T_OBJECT) {
+ psi_object *obj;
+
+ if (!instanceof_function(Z_OBJCE_P(iarg->_zv), psi_class_entry)) {
+ return NULL;
+ }
+
+ obj = PSI_OBJ(iarg->_zv, NULL);
+ arg_val->ptr = obj->data;
+ }
+ break;
EMPTY_SWITCH_DEFAULT_CASE();
}
}
for (i = 0; i < impl->decl->args->count; ++i) {
decl_arg *darg = impl->decl->args->args[i];
- impl->decl->call.args[i] = psi_do_let(darg);
+ if (!(impl->decl->call.args[i] = psi_do_let(darg))) {
+ goto cleanup;
+ }
}
}
psi_do_free(fre);
}
+ psi_do_clean(impl);
+ return;
+cleanup:
+ memset(&ret_val, 0, sizeof(ret_val));
+ psi_do_return(return_value, impl->stmts->ret.list[0], &ret_val);
psi_do_clean(impl);
}
+static void psi_object_free(zend_object *o)
+{
+ psi_object *obj = PSI_OBJ(NULL, o);
+
+ if (obj->data) {
+ // free(obj->data);
+ obj->data = NULL;
+ }
+ zend_object_std_dtor(o);
+}
+
+static zend_object *psi_object_init(zend_class_entry *ce)
+{
+ psi_object *o = ecalloc(1, sizeof(*o) + zend_object_properties_size(ce));
+
+ zend_object_std_init(&o->std, ce);
+ object_properties_init(&o->std, ce);
+ o->std.handlers = &psi_object_handlers;
+ return &o->std;
+}
+
PHP_MINIT_FUNCTION(psi)
{
PSI_ContextOps *ops = NULL;
+ zend_class_entry ce = {0};
REGISTER_INI_ENTRIES();
+ INIT_NS_CLASS_ENTRY(ce, "psi", "object", NULL);
+ psi_class_entry = zend_register_internal_class_ex(&ce, NULL);
+ psi_class_entry->create_object = psi_object_init;
+
+ memcpy(&psi_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers));
+ psi_object_handlers.offset = XtOffsetOf(psi_object, std);
+ psi_object_handlers.free_obj = psi_object_free;
+ psi_object_handlers.clone_obj = NULL;
+
#ifdef HAVE_LIBJIT
if (!strcasecmp(PSI_G(engine), "jit")) {
ops = PSI_Libjit();
#define BSIZE 256
+#define PSI_T_POINTER PSI_T_ASTERISK
typedef int token_t;
/* in php_psi.h */
val_ptr->ptr = ptr;
return val;
}
+
typedef struct impl_type {
char *name;
token_t type;
free(def);
}
+typedef struct const_type {
+ token_t type;
+ char *name;
+} const_type;
+
+static inline const_type *init_const_type(token_t type, const char *name) {
+ const_type *ct = calloc(1, sizeof(*ct));
+ ct->type = type;
+ ct->name = strdup(name);
+ return ct;
+}
+
+static inline void free_const_type(const_type *type) {
+ free(type->name);
+ free(type);
+}
+
+typedef struct constant {
+ const_type *type;
+ char *name;
+ impl_def_val *val;
+} constant;
+
+static inline constant *init_constant(const_type *type, const char *name, impl_def_val *val) {
+ constant *c = calloc(1, sizeof(*c));
+ c->type = type;
+ c->name = strdup(name);
+ c->val = val;
+ return c;
+}
+
+static inline void free_constant(constant *constant) {
+ free_const_type(constant->type);
+ free(constant->name);
+ free_impl_def_val(constant->val);
+ free(constant);
+}
+
+typedef struct constants {
+ size_t count;
+ constant **list;
+} constants;
+
+static inline constants *add_constant(constants *constants, constant *constant) {
+ if (!constants) {
+ constants = calloc(1, sizeof(*constants));
+ }
+ constants->list = realloc(constants->list, ++constants->count * sizeof(*constants->list));
+ constants->list[constants->count-1] = constant;
+ return constants;
+}
+
+static inline void free_constants(constants *c) {
+ size_t i;
+
+ for (i = 0; i < c->count; ++i) {
+ free_constant(c->list[i]);
+ }
+ free(c->list);
+ free(c);
+}
+
typedef struct impl_arg {
impl_type *type;
impl_var *var;
free(f);
}
+typedef struct num_exp {
+ token_t t;
+ union {
+ char *numb;
+ char *cnst;
+ decl_var *dvar;
+ } u;
+ token_t operator;
+ struct num_exp *operand;
+} num_exp;
+
+static inline num_exp *init_num_exp(token_t t, void *num) {
+ num_exp *exp = calloc(1, sizeof(*exp));
+ switch (exp->t = t) {
+ case PSI_T_NUMBER:
+ exp->u.numb = strdup(num);
+ break;
+ case PSI_T_NSNAME:
+ exp->u.cnst = strdup(num);
+ break;
+ case PSI_T_NAME:
+ exp->u.dvar = num;
+ break;
+ EMPTY_SWITCH_DEFAULT_CASE();
+ }
+ return exp;
+}
+
+static inline void free_num_exp(num_exp *exp) {
+ switch (exp->t) {
+ case PSI_T_NUMBER:
+ free(exp->u.numb);
+ break;
+ case PSI_T_NSNAME:
+ free(exp->u.cnst);
+ break;
+ case PSI_T_NAME:
+ free_decl_var(exp->u.dvar);
+ break;
+ EMPTY_SWITCH_DEFAULT_CASE();
+ }
+ if (exp->operand) {
+ free_num_exp(exp->operand);
+ }
+ free(exp);
+}
+
typedef struct let_calloc {
- size_t n;
- decl_type *type;
+ num_exp *nmemb;
+ num_exp *size;
} let_calloc;
-static inline let_calloc *init_let_calloc(long n, decl_type *type) {
+static inline let_calloc *init_let_calloc(num_exp *nmemb, num_exp *size) {
let_calloc *alloc = calloc(1, sizeof(*alloc));
- alloc->n = n;
- alloc->type = type;
+ alloc->nmemb = nmemb;
+ alloc->size = size;
return alloc;
}
static inline void free_let_calloc(let_calloc *alloc) {
- free_decl_type(alloc->type);
+ free_num_exp(alloc->nmemb);
+ free_num_exp(alloc->size);
free(alloc);
}
free(impls);
}
-typedef struct const_type {
- token_t type;
- char *name;
-} const_type;
-
-static inline const_type *init_const_type(token_t type, const char *name) {
- const_type *ct = calloc(1, sizeof(*ct));
- ct->type = type;
- ct->name = strdup(name);
- return ct;
-}
-
-static inline void free_const_type(const_type *type) {
- free(type->name);
- free(type);
-}
-
-typedef struct constant {
- const_type *type;
- char *name;
- impl_def_val *val;
-} constant;
-
-static inline constant *init_constant(const_type *type, const char *name, impl_def_val *val) {
- constant *c = calloc(1, sizeof(*c));
- c->type = type;
- c->name = strdup(name);
- c->val = val;
- return c;
-}
-
-static inline void free_constant(constant *constant) {
- free_const_type(constant->type);
- free(constant->name);
- free_impl_def_val(constant->val);
- free(constant);
-}
-
-typedef struct constants {
- size_t count;
- constant **list;
-} constants;
-
-static inline constants *add_constant(constants *constants, constant *constant) {
- if (!constants) {
- constants = calloc(1, sizeof(*constants));
- }
- constants->list = realloc(constants->list, ++constants->count * sizeof(*constants->list));
- constants->list[constants->count-1] = constant;
- return constants;
-}
-
-static inline void free_constants(constants *c) {
- size_t i;
-
- for (i = 0; i < c->count; ++i) {
- free_constant(c->list[i]);
- }
- free(c->list);
- free(c);
-}
#define PSI_ERROR 16
#define PSI_WARNING 32
"]" {RETURN(PSI_T_RBRACKET);}
"=" {RETURN(PSI_T_EQUALS);}
"$" {RETURN(PSI_T_DOLLAR);}
- "*" {RETURN(PSI_T_POINTER);}
- "&" {RETURN(PSI_T_REFERENCE);}
+ "*" {RETURN(PSI_T_ASTERISK);}
+ "&" {RETURN(PSI_T_AMPERSAND);}
+ "+" {RETURN(PSI_T_PLUS);}
+ "-" {RETURN(PSI_T_MINUS);}
+ "/" {RETURN(PSI_T_SLASH);}
[\r\n] { ++P->line; continue; }
[\t ]+ { continue; }
'TRUE' {RETURN(PSI_T_TRUE);}
'UNSIGNED' {RETURN(PSI_T_UNSIGNED);}
'STRING' {RETURN(PSI_T_STRING);}
'ARRAY' {RETURN(PSI_T_ARRAY);}
+ 'OBJECT' {RETURN(PSI_T_OBJECT);}
'FUNCTION' {RETURN(PSI_T_FUNCTION);}
'TYPEDEF' {RETURN(PSI_T_TYPEDEF);}
'STRUCT' {RETURN(PSI_T_STRUCT);}
'FREE' {RETURN(PSI_T_FREE);}
'STRLEN' {RETURN(PSI_T_STRLEN);}
'STRVAL' {RETURN(PSI_T_STRVAL);}
+ 'PATHVAL' {RETURN(PSI_T_PATHVAL);}
'INTVAL' {RETURN(PSI_T_INTVAL);}
'FLOATVAL' {RETURN(PSI_T_FLOATVAL);}
'BOOLVAL' {RETURN(PSI_T_BOOLVAL);}
'ARRVAL' {RETURN(PSI_T_ARRVAL);}
+ 'OBJVAL' {RETURN(PSI_T_OBJVAL);}
'CALLOC' {RETURN(PSI_T_CALLOC);}
+ 'TO_OBJECT' {RETURN(PSI_T_TO_OBJECT);}
'TO_ARRAY' {RETURN(PSI_T_TO_ARRAY);}
'TO_STRING' {RETURN(PSI_T_TO_STRING);}
'TO_INT' {RETURN(PSI_T_TO_INT);}
#define PSI_T_NAME 1
-#define PSI_T_FREE 2
-#define PSI_T_SET 3
-#define PSI_T_LET 4
-#define PSI_T_RETURN 5
-#define PSI_T_LIB 6
-#define PSI_T_INT 7
-#define PSI_T_UNSIGNED 8
-#define PSI_T_EOF 9
-#define PSI_T_QUOTED_STRING 10
-#define PSI_T_EOS 11
-#define PSI_T_STRUCT 12
-#define PSI_T_LBRACE 13
-#define PSI_T_RBRACE 14
-#define PSI_T_COLON 15
-#define PSI_T_LPAREN 16
-#define PSI_T_NUMBER 17
-#define PSI_T_RPAREN 18
-#define PSI_T_BOOL 19
-#define PSI_T_FLOAT 20
-#define PSI_T_STRING 21
-#define PSI_T_CONST 22
-#define PSI_T_NSNAME 23
-#define PSI_T_EQUALS 24
-#define PSI_T_TYPEDEF 25
-#define PSI_T_VOID 26
-#define PSI_T_LBRACKET 27
-#define PSI_T_RBRACKET 28
-#define PSI_T_COMMA 29
-#define PSI_T_DOUBLE 30
-#define PSI_T_INT8 31
-#define PSI_T_UINT8 32
-#define PSI_T_INT16 33
-#define PSI_T_UINT16 34
-#define PSI_T_INT32 35
-#define PSI_T_UINT32 36
-#define PSI_T_INT64 37
-#define PSI_T_UINT64 38
-#define PSI_T_FUNCTION 39
-#define PSI_T_REFERENCE 40
-#define PSI_T_NULL 41
-#define PSI_T_TRUE 42
-#define PSI_T_FALSE 43
-#define PSI_T_DOLLAR 44
-#define PSI_T_CALLOC 45
-#define PSI_T_ARRVAL 46
-#define PSI_T_STRLEN 47
-#define PSI_T_STRVAL 48
-#define PSI_T_FLOATVAL 49
-#define PSI_T_INTVAL 50
-#define PSI_T_BOOLVAL 51
-#define PSI_T_TO_ARRAY 52
-#define PSI_T_TO_STRING 53
-#define PSI_T_TO_INT 54
-#define PSI_T_TO_FLOAT 55
-#define PSI_T_TO_BOOL 56
-#define PSI_T_MIXED 57
-#define PSI_T_ARRAY 58
-#define PSI_T_POINTER 59
+#define PSI_T_PLUS 2
+#define PSI_T_MINUS 3
+#define PSI_T_SLASH 4
+#define PSI_T_ASTERISK 5
+#define PSI_T_FREE 6
+#define PSI_T_SET 7
+#define PSI_T_LET 8
+#define PSI_T_RETURN 9
+#define PSI_T_LIB 10
+#define PSI_T_INT 11
+#define PSI_T_UNSIGNED 12
+#define PSI_T_EOF 13
+#define PSI_T_QUOTED_STRING 14
+#define PSI_T_EOS 15
+#define PSI_T_STRUCT 16
+#define PSI_T_LBRACE 17
+#define PSI_T_RBRACE 18
+#define PSI_T_COLON 19
+#define PSI_T_LPAREN 20
+#define PSI_T_NUMBER 21
+#define PSI_T_RPAREN 22
+#define PSI_T_BOOL 23
+#define PSI_T_FLOAT 24
+#define PSI_T_STRING 25
+#define PSI_T_CONST 26
+#define PSI_T_NSNAME 27
+#define PSI_T_EQUALS 28
+#define PSI_T_TYPEDEF 29
+#define PSI_T_VOID 30
+#define PSI_T_LBRACKET 31
+#define PSI_T_RBRACKET 32
+#define PSI_T_COMMA 33
+#define PSI_T_DOUBLE 34
+#define PSI_T_INT8 35
+#define PSI_T_UINT8 36
+#define PSI_T_INT16 37
+#define PSI_T_UINT16 38
+#define PSI_T_INT32 39
+#define PSI_T_UINT32 40
+#define PSI_T_INT64 41
+#define PSI_T_UINT64 42
+#define PSI_T_FUNCTION 43
+#define PSI_T_AMPERSAND 44
+#define PSI_T_NULL 45
+#define PSI_T_TRUE 46
+#define PSI_T_FALSE 47
+#define PSI_T_DOLLAR 48
+#define PSI_T_CALLOC 49
+#define PSI_T_OBJVAL 50
+#define PSI_T_ARRVAL 51
+#define PSI_T_PATHVAL 52
+#define PSI_T_STRLEN 53
+#define PSI_T_STRVAL 54
+#define PSI_T_FLOATVAL 55
+#define PSI_T_INTVAL 56
+#define PSI_T_BOOLVAL 57
+#define PSI_T_TO_OBJECT 58
+#define PSI_T_TO_ARRAY 59
+#define PSI_T_TO_STRING 60
+#define PSI_T_TO_INT 61
+#define PSI_T_TO_FLOAT 62
+#define PSI_T_TO_BOOL 63
+#define PSI_T_MIXED 64
+#define PSI_T_ARRAY 65
+#define PSI_T_OBJECT 66
}
%nonassoc NAME.
+%left PLUS MINUS SLASH ASTERISK.
%fallback NAME FREE SET LET RETURN LIB INT UNSIGNED.
file ::= blocks.
func = init_impl_func(NAME->text, args, type, 0);
free(NAME);
}
-impl_func(func) ::= FUNCTION REFERENCE NSNAME(NAME) impl_args(args) COLON impl_type(type). {
+impl_func(func) ::= FUNCTION AMPERSAND NSNAME(NAME) impl_args(args) COLON impl_type(type). {
func = init_impl_func(NAME->text, args, type, 1);
free(NAME);
}
var = init_impl_var(T->text, 0);
free(T);
}
-impl_var(var) ::= REFERENCE DOLLAR NAME(T). {
+impl_var(var) ::= AMPERSAND DOLLAR NAME(T). {
var = init_impl_var(T->text, 1);
free(T);
}
%type let_value {let_value*}
%destructor let_value {free_let_value($$);}
-let_value(val) ::= CALLOC(F) LPAREN NUMBER(N) COMMA decl_type(t) RPAREN. {
- val = init_let_value(
- init_let_func(F->type, F->text,
- init_let_calloc(
- atol(N->text), t
- )
- ), NULL, 0
- );
+let_value(val) ::= CALLOC(F) LPAREN let_calloc(alloc) RPAREN. {
+ val = init_let_value(init_let_func(F->type, F->text, alloc), NULL, 0);
free(F);
- free(N);
}
+
+%type let_calloc {let_calloc*}
+%destructor let_calloc {free_let_calloc($$);}
+let_calloc(alloc) ::= num_exp(nmemb) COMMA num_exp(size). {
+ alloc = init_let_calloc(nmemb, size);
+}
+
+%token_class num_exp_token NUMBER NSNAME.
+%token_class num_exp_op_token PLUS MINUS ASTERISK SLASH.
+%type num_exp {num_exp*}
+%destructor num_exp {free_num_exp($$);}
+num_exp(exp) ::= num_exp_token(tok). {
+ exp = init_num_exp(tok->type, tok->text);
+ free(tok);
+}
+num_exp(exp) ::= decl_var(var). {
+ exp = init_num_exp(PSI_T_NAME, var);
+}
+num_exp(exp) ::= num_exp(exp_) num_exp_op_token(operator_) num_exp(operand_). {
+ exp_->operator = operator_->type;
+ exp_->operand = operand_;
+ exp = exp_;
+ free(operator_);
+}
+
let_value(val) ::= reference(r) let_func(func) LPAREN impl_var(var) RPAREN. {
val = init_let_value(func, var, r);
}
val = init_let_value(NULL, NULL, r);
}
-%token_class let_func_token ARRVAL STRLEN STRVAL FLOATVAL INTVAL BOOLVAL.
+%token_class let_func_token OBJVAL ARRVAL PATHVAL STRLEN STRVAL FLOATVAL INTVAL BOOLVAL.
%type let_func {let_func*}
%destructor let_func {free_let_func($$);}
let_func(func) ::= let_func_token(T). {
vals = add_inner_set_value(vals_, val);
}
-%token_class set_func_token TO_ARRAY TO_STRING TO_INT TO_FLOAT TO_BOOL VOID.
+%token_class set_func_token TO_OBJECT TO_ARRAY TO_STRING TO_INT TO_FLOAT TO_BOOL VOID.
%type set_func {set_func*}
%destructor set_func {free_set_func($$);}
set_func(func) ::= set_func_token(T). {
call = init_free_call(F->text, vars);
}
-%token_class impl_type_token VOID MIXED BOOL INT FLOAT STRING ARRAY.
+%token_class impl_type_token VOID MIXED BOOL INT FLOAT STRING ARRAY OBJECT.
%type impl_type {impl_type*}
%destructor impl_type {free_impl_type($$);}
impl_type(type_) ::= impl_type_token(T). {
%type reference {char}
reference(r) ::= . {r = 0;}
-reference(r) ::= REFERENCE. {r = 1;}
+reference(r) ::= AMPERSAND. {r = 1;}
%type indirection {unsigned}
indirection(i) ::= . {i = 0;}
indirection(i) ::= pointers(p). {i = p;}
%type pointers {unsigned}
-pointers(p) ::= POINTER. {p = 1;}
-pointers(p) ::= pointers(P) POINTER. {p = P+1;}
+pointers(p) ::= ASTERISK. {p = 1;}
+pointers(p) ::= pointers(P) ASTERISK. {p = P+1;}