/* * Register function * (C) 2006, Pascal Schmidt * see file ../doc/LICENSE for license */ #include #include #include #include #include "stdlib.h" /* * stdlib function definition */ typedef struct { char *name; call_func vector; unsigned int args; char *proto; char rettype; } stdlib_func; /* * stdlib int constant definition */ typedef struct { char *name; int value; } stdlib_int_const; /* * stdlib float constant definition */ typedef struct { char *name; double value; } stdlib_float_const; /* * stdlib int constants to register */ static stdlib_int_const ints[] = { { "stdin", 1 }, { "stdout", 2 }, { "stderr", 3 }, { "FLT_DIG", DBL_DIG }, { "FLT_MANT_DIG", DBL_MANT_DIG }, { "FLT_MAX_EXP", DBL_MAX_EXP }, { "FLT_MIN_EXP", DBL_MIN_EXP }, { "FLT_RADIX", FLT_RADIX }, { "INT_MIN", INT_MIN }, { "INT_MAX", INT_MAX }, { "RAND_MAX", RAND_MAX }, { NULL, 0 } }; static stdlib_float_const floats[] = { { "FLT_EPSILON", DBL_EPSILON }, { "FLT_MAX", DBL_MAX }, { "FLT_MIN", DBL_MIN }, { NULL, 0.0 } }; /* * stdlib functions to register */ static stdlib_func std[] = { /* runtime system functions */ { "type_of", rt_type_of, 1, "?", 's' }, { "tmpl_of", rt_tmpl_of, 1, "?", '?' }, { "is_void", rt_is_void, 1, "?", 'b' }, { "is_bool", rt_is_bool, 1, "?", 'b' }, { "is_int", rt_is_int, 1, "?", 'b' }, { "is_float", rt_is_float, 1, "?", 'b' }, { "is_string", rt_is_string, 1, "?", 'b' }, { "is_array", rt_is_array, 1, "?", 'b' }, { "is_struct", rt_is_struct, 1, "?", 'b' }, { "is_fn", rt_is_fn, 1, "?", 'b' }, { "is_resource", rt_is_resource, 1, "?", 'b' }, { "is_a", rt_is_a, 2, "?s", 'b' }, { "is_function", rt_is_function, 1, "s", 'b' }, { "is_var", rt_is_var, 1, "s", 'b' }, { "is_tmpl", rt_is_tmpl, 1, "s", 'b' }, { "is_local", rt_is_local, 1, "s", 'b' }, { "is_global", rt_is_global, 1, "s", 'b' }, { "set", rt_set, 2, "s?", 'b' }, { "get", rt_get, 1, "s", '?' }, { "get_static", rt_get_static, 2, "ss", '?' }, { "unset", rt_unset, 0, "", 'v' }, { "assert", rt_assert, 0, "", 'v' }, { "global", rt_global, 0, "", 'v' }, { "cast_to", rt_cast_to, 2, "?s", '?' }, { "versions", rt_versions, 0, "", 'c' }, /* system environment functions */ { "exit", sys_exit, 1, "i", 'v' }, { "getenv", sys_getenv, 1, "s", '?' }, { "system", sys_system, 1, "s", '?' }, /* random number functions */ { "rand", rnd_random, 2, "ii", 'i' }, { "srand", rnd_srandom, 1, "i", 'v' }, /* printing functions */ { "print", print_print, 0, "", 'v' }, { "dump", print_dump, 0, "", 'v' }, { "sprintf", print_sprintf, 1, "s", 's' }, { "printf", print_printf, 1, "s", 'v' }, /* array functions */ { "mkarray", array_mkarray, 0, "", 'a' }, { "qsort", array_sort, 1, "a", 'a' }, { "is_sorted", array_is_sorted, 1, "a", 'b' }, { "array_unset", array_unset, 2, "ai", 'a' }, { "array_compact", array_compact, 1, "a", 'a' }, { "array_search", array_search, 2, "a?", '?' }, { "array_merge", array_merge, 0, "", 'a' }, { "array_reverse", array_reverse, 1, "a", 'a' }, /* struct functions */ { "mkstruct", struct_mkstruct, 0, "", 'c' }, { "struct_get", struct_get, 2, "cs", '?' }, { "struct_set", struct_set, 3, "cs?", 'c' }, { "struct_unset", struct_unset, 2, "cs", 'c' }, { "struct_fields", struct_fields, 1, "c", 'a' }, { "struct_methods", struct_methods, 1, "c", 'a' }, { "is_field", struct_is_field, 2, "cs", 'b' }, { "is_method", struct_is_method, 2, "cs", 'b' }, { "struct_merge", struct_merge, 0, "", 'c' }, /* string functions */ { "strlen", str_length, 1, "S", 'i' }, { "strcat", str_concat, 0, "", 's' }, { "strchr", str_leftmost, 2, "SS", '?' }, { "strrchr", str_rightmost, 2, "SS", '?' }, { "strstr", str_strpos, 2, "SS", '?' }, { "strspn", str_span, 2, "SS", 'i' }, { "strcspn", str_cspan, 2, "SS", 'i' }, { "strpbrk", str_pbrk, 2, "SS", '?' }, { "strcoll", str_coll, 2, "SS", 'i' }, { "tolower", str_lower, 1, "S", 's' }, { "toupper", str_upper, 1, "S", 's' }, { "isalnum", str_is_alnum, 1, "S", 'b' }, { "isalpha", str_is_alpha, 1, "S", 'b' }, { "iscntrl", str_is_cntrl, 1, "S", 'b' }, { "isdigit", str_is_digit, 1, "S", 'b' }, { "isgraph", str_is_graph, 1, "S", 'b' }, { "islower", str_is_lower, 1, "S", 'b' }, { "isprint", str_is_print, 1, "S", 'b' }, { "ispunct", str_is_punct, 1, "S", 'b' }, { "isspace", str_is_space, 1, "S", 'b' }, { "isupper", str_is_upper, 1, "S", 'b' }, { "isxdigit", str_is_xdigit, 1, "S", 'b' }, { "substr", str_mid, 2, "Si*", 's' }, { "left", str_left, 2, "Si", 's' }, { "right", str_right, 2, "Si", 's' }, { "ord", str_ord, 1, "S", '?' }, { "chr", str_chr, 1, "i", 's' }, { "explode", str_explode, 1, "S", 'a' }, { "implode", str_implode, 1, "a", 's' }, { "ltrim", str_ltrim, 1, "S", 's' }, { "rtrim", str_rtrim, 1, "S", 's' }, { "trim", str_trim, 1, "S", 's' }, /* file I/O functions */ { "is_file_resource", file_is_resource, 1, "r", 'b' }, { "fopen", file_open, 2, "ss", '?' }, { "fseek", file_seek, 2, "ri", 'b' }, { "ftell", file_tell, 1, "r", '?' }, { "fread", file_read, 2, "ri", '?' }, { "fwrite", file_write, 2, "rS", '?' }, { "setbuf", file_setbuf, 2, "rb", 'b' }, { "fflush", file_flush, 1, "r", 'b' }, { "feof", file_is_eof, 1, "r", 'b' }, { "ferror", file_is_error, 1, "r", 'b' }, { "clearerr", file_clearerr, 1, "r", 'v' }, { "fclose", file_close, 1, "r", 'b' }, { "remove", file_remove, 1, "s", 'b' }, { "rename", file_rename, 1, "s", 'b' }, { "errno", file_errno, 0, "", 'i' }, { "strerror", file_strerror, 1, "i", 's' }, { "fgetc", file_getc, 1, "r", '?' }, { "fgets", file_gets, 1, "r", '?' }, /* locale functions */ { "getlocale", lc_getlocale, 0, "", 's' }, { "setlocale", lc_setlocale, 1, "s", '?' }, { "localeconv", lc_localeconv, 0, "", '?' }, /* dictionary functions */ { "is_dict_resource", dict_is_resource, 1, "r", 'b' }, { "dopen", dict_open, 1, "i", '?' }, { "dread", dict_read, 2, "rS", '?' }, { "dwrite", dict_write, 3, "rS?", 'b' }, { "dremove", dict_remove, 2, "rS", 'b' }, { "dexists", dict_exists, 2, "rS", 'b' }, { "dclose", dict_close, 1, "r", 'v' }, /* math functions */ { "exp", math_exp, 1, "F", 'f' }, { "log", math_log, 1, "F", 'f' }, { "log10", math_log10, 1, "F", 'f' }, { "sqrt", math_sqrt, 1, "F", 'f' }, { "ceil", math_ceil, 1, "F", 'f' }, { "floor", math_floor, 1, "F", 'f' }, { "fabs", math_fabs, 1, "F", 'f' }, { "sin", math_sin, 1, "F", 'f' }, { "cos", math_cos, 1, "F", 'f' }, { "tan", math_tan, 1, "F", 'f' }, { "asin", math_asin, 1, "F", 'f' }, { "acos", math_acos, 1, "F", 'f' }, { "atan", math_atan, 1, "F", 'f' }, { "sinh", math_sinh, 1, "F", 'f' }, { "cosh", math_cosh, 1, "F", 'f' }, { "tanh", math_tanh, 1, "F", 'f' }, { "abs", math_abs, 1, "I", 'i' }, /* date and time functions */ { "time", time_time, 0, "", 'i' }, { "gmtime", time_gmtime, 1, "i", 'c' }, { "localtime", time_localtime, 1, "i", 'c' }, { "mktime", time_mktime, 1, "c", 'i' }, { "asctime", time_asctime, 1, "c", 's' }, { "ctime", time_ctime, 1, "i", 's' }, { "strftime", time_strftime, 2, "sc", 's' }, /* functions on functions */ { "is_builtin", fn_is_builtin, 1, "p", 'b' }, { "is_userdef", fn_is_userdef, 1, "p", 'b' }, { "function_name", fn_name, 1, "p", 's' }, { "call", fn_call, 1, "p", '?' }, { "call_array", fn_call_array, 2, "pa", '?' }, { "call_method", fn_call_method, 2, "pc", '?' }, { "call_method_array",fn_call_method_array, 3, "pca", '?' }, { "prototype", fn_prototype, 1, "p", 'c' }, { "map", fn_map, 2, "pa", 'a' }, { "filter", fn_filter, 2, "pa", 'a' }, { "foldl", fn_foldl, 3, "p?a", '?' }, { "foldr", fn_foldr, 3, "pa?", '?' }, { "take_while", fn_take_while, 2, "pa", 'a' }, { "drop_while", fn_drop_while, 2, "pa", 'a' }, /* list functions */ { "nil", list_nil, 0, "", 'a' }, { "cons", list_cons, 2, "?a", 'a' }, { "head", list_head, 1, "a", '?' }, { "tail", list_tail, 1, "a", 'a' }, { "last", list_last, 1, "a", '?' }, { "init", list_init, 1, "a", 'a' }, { "take", list_take, 2, "ai", 'a' }, { "drop", list_drop, 2, "ai", 'a' }, { "length", list_length, 1, "a", 'i' }, { "null", list_null, 1, "a", 'b' }, { "elem", list_elem, 2, "a?", 'b' }, { "intersperse", list_intersperse, 2, "a?", 'a' }, { "replicate", list_replicate, 2, "?i", 'a' }, /* foreign function interface */ { "is_dyn_resource", dyn_is_resource, 1, "r", 'b' }, { "dyn_supported", dyn_supported, 0, "", 'b' }, { "dyn_open", dyn_open, 1, "s", '?' }, { "dyn_close", dyn_close, 1, "r", 'v' }, { "dyn_fn_pointer", dyn_fn_pointer, 1, "rs", '?' }, { "dyn_call_void", dyn_call_void, 2, "rs", 'v' }, { "dyn_call_int", dyn_call_int, 2, "rs", '?' }, { "dyn_call_float", dyn_call_float, 2, "rs", '?' }, { "dyn_call_ptr", dyn_call_ptr, 2, "rs", '?' }, { "cfloat", dyn_c_float, 1, "F", '?' }, /* memory handling functions */ { "is_mem_resource", mem_is_resource, 1, "r", 'b' }, { "malloc", mem_malloc, 1, "i", '?' }, { "calloc", mem_calloc, 2, "ii", '?' }, { "realloc", mem_realloc, 2, "ri", 'b' }, { "free", mem_free, 1, "r", 'v' }, { "cnull", mem_cnull, 0, "", 'r' }, { "is_null", mem_is_null, 1, "r", 'b' }, { "cstring", mem_cstring, 1, "S", '?' }, { "mputchar", mem_put_char, 3, "rii", 'b' }, { "mputshort", mem_put_short, 3, "rii", 'b' }, { "mputint", mem_put_int, 3, "rii", 'b' }, { "mputfloat", mem_put_float, 3, "rif", 'b' }, { "mputdouble", mem_put_double, 3, "rif", 'b' }, { "mputstring", mem_put_string, 3, "riS", 'b' }, { "mputptr", mem_put_pointer, 3, "rir", 'b' }, { "mgetchar", mem_get_char, 2, "ri", '?' }, { "mgetshort", mem_get_short, 2, "ri", '?' }, { "mgetint", mem_get_int, 2, "ri", '?' }, { "mgetfloat", mem_get_float, 2, "ri", '?' }, { "mgetdouble", mem_get_double, 2, "ri", '?' }, { "mgetstring", mem_get_string, 3, "rii", '?' }, { "mgetptr", mem_get_pointer, 3, "rib", '?' }, { "mstring", mem_string, 2, "ri", '?' }, { "is_rw", mem_is_rw, 1, "r", 'b' }, { "msize", mem_size, 1, "r", '?' }, { "memcpy", mem_cpy, 5, "ririi",'b' }, { "memmove", mem_move, 5, "ririi",'b' }, { "memcmp", mem_cmp, 5, "ririi",'?' }, { "memchr", mem_chr, 4, "riii", '?' }, { "memset", mem_set, 4, "riii", 'b' }, /* PCRE regular expression functions */ { "is_pcre_resource", preg_is_resource, 1, "r", 'b' }, { "pcre_supported", preg_supported, 0, "", 'b' }, { "pcre_compile", preg_compile, 2, "si", '?' }, { "pcre_match", preg_match, 2, "rsi", '?' }, { "pcre_exec", preg_exec, 2, "rsi", '?' }, { "pcre_free", preg_free, 1, "r", 'v' }, /* list terminator */ { NULL, NULL, 0, NULL, 0 } }; /* * Register command line arguments */ static void register_args(arena_state *s, int argc, char **argv) { value *val, *vector; int i; val = value_make_int(argc); symtab_stack_add_variable(s, "argc", val); value_free(val); vector = value_make_array(); for (i = 0; i < argc; i++) { val = value_make_string(argv[i]); value_add_to_array(vector, val); value_free(val); } symtab_stack_add_variable(s, "argv", vector); value_free(vector); } /* * Register stdlib functions * * This function registers the stdlib functions in the current * symbol table. Usually this means the global symbol table. */ void stdlib_register(arena_state *s, int argc, char **argv) { value *val; signature sig; unsigned int i; sig.type = FUNCTION_TYPE_BUILTIN; i = 0; while (std[i].name) { sig.args = std[i].args; sig.name = std[i].name; sig.proto = std[i].proto; sig.call_u.builtin_vector = std[i].vector; sig.rettype = std[i].rettype; symtab_stack_add_function(s, std[i].name, &sig); i++; } i = 0; while (ints[i].name) { val = value_make_int(ints[i].value); symtab_stack_add_variable(s, ints[i].name, val); value_free(val); i++; } i = 0; while (floats[i].name) { val = value_make_float(floats[i].value); symtab_stack_add_variable(s, floats[i].name, val); value_free(val); i++; } file_init(s); preg_init(s); register_args(s, argc, argv); }