diff --git a/src/arobject.h b/src/arobject.h index b7cf226..069fd0d 100644 --- a/src/arobject.h +++ b/src/arobject.h @@ -35,7 +35,8 @@ typedef enum { __number__, field_length, __getattribute__, - __set_attr__, + __setattr__, + __setitem__, __hash__, __repr__, diff --git a/src/parser/assignable/assign/assign.c b/src/parser/assignable/assign/assign.c index 042595a..be980f6 100644 --- a/src/parser/assignable/assign/assign.c +++ b/src/parser/assignable/assign/assign.c @@ -84,12 +84,22 @@ ParsedValueReturn parse_assign(char *file, DArray *tokens, return (ParsedValueReturn){err, NULL}; } (*index)++; + ArErr err = error_if_finished(file, tokens, index); + if (err.exists) { + free_parsed(assign_to); + free(assign_to); + return (ParsedValueReturn){err, NULL}; + } token = darray_get(tokens, *index); ParsedValueReturn from = parse_token(file, tokens, index, true); if (from.err.exists) { + free_parsed(assign_to); + free(assign_to); return from; } if (!from.value) { + free_parsed(assign_to); + free(assign_to); return (ParsedValueReturn){create_err(token->line, token->column, token->length, file, "Syntax Error", "expected body"), @@ -110,12 +120,6 @@ ParsedValueReturn parse_assign(char *file, DArray *tokens, ParsedValue *parsedValue = checked_malloc(sizeof(ParsedValue)); parsedValue->type = AST_ASSIGN; parsedValue->data = assign; - ArErr err = error_if_finished(file, tokens, index); - if (err.exists) { - free_parsed(parsedValue); - free(parsedValue); - return (ParsedValueReturn){err, NULL}; - } assign->from = from.value; return (ParsedValueReturn){no_err, parsedValue}; } diff --git a/src/parser/parentheses-and-anonymous-function/parentheses-and-anonymous-function.c b/src/parser/parentheses-and-anonymous-function/parentheses-and-anonymous-function.c index 2a3a63e..4305b75 100644 --- a/src/parser/parentheses-and-anonymous-function/parentheses-and-anonymous-function.c +++ b/src/parser/parentheses-and-anonymous-function/parentheses-and-anonymous-function.c @@ -47,6 +47,7 @@ ParsedValueReturn parse_parentheses(char *file, DArray *tokens, size_t *index) { "Syntax Error", "expected comma"), NULL}; } + (*index)++; skip_newlines_and_indents(tokens, index); err = error_if_finished(file, tokens, index); if (err.exists) { diff --git a/src/runtime/call/call.c b/src/runtime/call/call.c index dd387e6..3e28f7a 100644 --- a/src/runtime/call/call.c +++ b/src/runtime/call/call.c @@ -132,36 +132,58 @@ void run_call(ArgonObject *original_object, size_t argc, ArgonObject **argv, new_string_object(key.data, key.length, 0, hash), value, 0); } - StackFrame new_stackFrame = { - {object->value.argon_fn->translated.registerCount, - object->value.argon_fn->translated.registerAssignment, - NULL, - {object->value.argon_fn->bytecode, sizeof(uint8_t), - object->value.argon_fn->bytecode_length, - object->value.argon_fn->bytecode_length, false}, - object->value.argon_fn->translated.constants, - object->value.argon_fn->translated.path}, - {ar_alloc(object->value.argon_fn->translated.registerCount * - sizeof(ArgonObject *)), - 0, - object->value.argon_fn->translated.path, - NULL, - state->currentStackFramePointer, - {}, - {}}, - scope, - *state->currentStackFramePointer, - (*state->currentStackFramePointer)->depth + 1}; - for (size_t i = 0; i < new_stackFrame.translated.registerCount; i++) { - new_stackFrame.state.registers[i] = NULL; - } if (CStackFrame) { + StackFrame new_stackFrame = { + {object->value.argon_fn->translated.registerCount, + object->value.argon_fn->translated.registerAssignment, + NULL, + {object->value.argon_fn->bytecode, sizeof(uint8_t), + object->value.argon_fn->bytecode_length, + object->value.argon_fn->bytecode_length, false}, + object->value.argon_fn->translated.constants, + object->value.argon_fn->translated.path}, + {ar_alloc(object->value.argon_fn->translated.registerCount * + sizeof(ArgonObject *)), + 0, + object->value.argon_fn->translated.path, + NULL, + state->currentStackFramePointer, + {}, + {}}, + scope, + *state->currentStackFramePointer, + (*state->currentStackFramePointer)->depth + 1}; + for (size_t i = 0; i < new_stackFrame.translated.registerCount; i++) { + new_stackFrame.state.registers[i] = NULL; + } runtime(new_stackFrame.translated, new_stackFrame.state, new_stackFrame.stack, err); state->registers[0] = new_stackFrame.state.registers[0]; } else { StackFrame *currentStackFrame = ar_alloc(sizeof(StackFrame)); - *currentStackFrame = new_stackFrame; + *currentStackFrame = (StackFrame){ + {object->value.argon_fn->translated.registerCount, + object->value.argon_fn->translated.registerAssignment, + NULL, + {object->value.argon_fn->bytecode, sizeof(uint8_t), + object->value.argon_fn->bytecode_length, + object->value.argon_fn->bytecode_length, false}, + object->value.argon_fn->translated.constants, + object->value.argon_fn->translated.path}, + {ar_alloc(object->value.argon_fn->translated.registerCount * + sizeof(ArgonObject *)), + 0, + object->value.argon_fn->translated.path, + NULL, + state->currentStackFramePointer, + {}, + {}}, + scope, + *state->currentStackFramePointer, + (*state->currentStackFramePointer)->depth + 1}; + for (size_t i = 0; i < (*currentStackFrame).translated.registerCount; i++) { + (*currentStackFrame).state.registers[i] = NULL; + } *state->currentStackFramePointer = currentStackFrame; if ((*state->currentStackFramePointer)->depth >= 10000) { double logval = diff --git a/src/runtime/objects/dictionary/dictionary.c b/src/runtime/objects/dictionary/dictionary.c index f0d7f58..9e164e2 100644 --- a/src/runtime/objects/dictionary/dictionary.c +++ b/src/runtime/objects/dictionary/dictionary.c @@ -146,14 +146,36 @@ ArgonObject *create_ARGON_DICTIONARY_TYPE___get_attr__(size_t argc, } -ArgonObject *create_ARGON_DICTIONARY_TYPE___set_attr__(size_t argc, +ArgonObject *create_ARGON_DICTIONARY_TYPE___setattr__(size_t argc, ArgonObject **argv, ArErr *err, RuntimeState *state) { (void)state; if (argc != 3) { *err = create_err(0, 0, 0, "", "Runtime Error", - "__set_attr__ expects 2 argument, got %" PRIu64, argc); + "__setattr__ expects 2 argument, got %" PRIu64, argc); + return ARGON_NULL; + } + ArgonObject *object = argv[0]; + ArgonObject *key = argv[1]; + ArgonObject *value = argv[2]; + int64_t hash = hash_object(key, err, state); + if (err->exists) { + return ARGON_NULL; + } + hashmap_insert_GC(object->value.as_hashmap, hash, key, value, 0); + return value; +} + + +ArgonObject *create_ARGON_DICTIONARY_TYPE___setitem__(size_t argc, + ArgonObject **argv, + ArErr *err, + RuntimeState *state) { + (void)state; + if (argc != 3) { + *err = create_err(0, 0, 0, "", "Runtime Error", + "__setitem__ expects 2 argument, got %" PRIu64, argc); return ARGON_NULL; } ArgonObject *object = argv[0]; @@ -179,9 +201,13 @@ void create_ARGON_DICTIONARY_TYPE() { create_argon_native_function("__get_attr__", create_ARGON_DICTIONARY_TYPE___get_attr__)); add_builtin_field( - ARGON_DICTIONARY_TYPE, __set_attr__, - create_argon_native_function("__set_attr__", - create_ARGON_DICTIONARY_TYPE___set_attr__)); + ARGON_DICTIONARY_TYPE, __setattr__, + create_argon_native_function("__setattr__", + create_ARGON_DICTIONARY_TYPE___setattr__)); + add_builtin_field( + ARGON_DICTIONARY_TYPE, __setitem__, + create_argon_native_function("__setitem__", + create_ARGON_DICTIONARY_TYPE___setitem__)); add_builtin_field(ARGON_DICTIONARY_TYPE, __string__, create_argon_native_function( "__string__", create_ARGON_DICTIONARY_TYPE___string__)); diff --git a/src/runtime/objects/number/number.c b/src/runtime/objects/number/number.c index fa3b647..58b56cd 100644 --- a/src/runtime/objects/number/number.c +++ b/src/runtime/objects/number/number.c @@ -11,6 +11,7 @@ #include #include #include +#include ArgonObject *ARGON_NUMBER_TYPE; @@ -268,6 +269,64 @@ ArgonObject *ARGON_NUMBER_TYPE___multiply__(size_t argc, ArgonObject **argv, } } + + +static inline uint64_t mix64(uint64_t x) { + x ^= x >> 33; + x *= 0xff51afd7ed558ccdULL; + x ^= x >> 33; + x *= 0xc4ceb9fe1a85ec53ULL; + x ^= x >> 33; + return x; +} + +uint64_t hash_mpz(const mpz_t z) { + // Export to raw bytes (big-endian for consistency) + size_t count; + unsigned char *data = mpz_export(NULL, &count, 1, 1, 1, 0, z); + + // FNV-1a over bytes + uint64_t h = 1469598103934665603ULL; + for (size_t i = 0; i < count; i++) { + h ^= data[i]; + h *= 1099511628211ULL; + } + + // Include sign bit + if (mpz_sgn(z) < 0) + h = ~h; + + // Free the temporary buffer allocated by mpz_export + free(data); + + return mix64(h); +} + +uint64_t hash_mpq(mpq_t q) { + uint64_t h_num = hash_mpz(mpq_numref(q)); + uint64_t h_den = hash_mpz(mpq_denref(q)); + + // Combine using a standard 64-bit hash mix (boost-style) + uint64_t h = h_num ^ (h_den + 0x9e3779b97f4a7c15ULL + (h_num << 6) + (h_num >> 2)); + return mix64(h); +} + +ArgonObject *ARGON_NUMBER_TYPE___hash__(size_t argc, ArgonObject **argv, + ArErr *err, RuntimeState *state) { + (void)state; + if (argc != 1) { + *err = create_err(0, 0, 0, "", "Runtime Error", + "__hash__ expects 1 arguments, got %" PRIu64, argc); + } + uint64_t hash; + if (argv[0]->value.as_number->is_int64) { + hash = mix64(argv[0]->value.as_number->n.i64); + } else { + hash = hash_mpq(*argv[0]->value.as_number->n.mpq); + } + return new_number_object_from_int64(hash); +} + ArgonObject *ARGON_NUMBER_TYPE___division__(size_t argc, ArgonObject **argv, ArErr *err, RuntimeState *state) { (void)state; @@ -497,7 +556,6 @@ void init_small_ints() { for (int64_t i = 0; i <= small_ints_max - small_ints_min; i++) { int64_t n = i + small_ints_min; small_ints[i].type = TYPE_NUMBER; - small_ints[i].built_in_slot_length = 0; small_ints[i].dict = NULL; small_ints[i].value.as_number = &small_ints_as_number[i]; add_builtin_field(&small_ints[i], __class__, ARGON_NUMBER_TYPE); @@ -520,6 +578,9 @@ void create_ARGON_NUMBER_TYPE() { add_builtin_field( ARGON_NUMBER_TYPE, __number__, create_argon_native_function("__number__", ARGON_NUMBER_TYPE___number__)); + add_builtin_field( + ARGON_NUMBER_TYPE, __hash__, + create_argon_native_function("__hash__", ARGON_NUMBER_TYPE___hash__)); add_builtin_field(ARGON_NUMBER_TYPE, __boolean__, create_argon_native_function( "__boolean__", ARGON_NUMBER_TYPE___boolean__)); diff --git a/src/runtime/objects/object.c b/src/runtime/objects/object.c index 0858567..c2666af 100644 --- a/src/runtime/objects/object.c +++ b/src/runtime/objects/object.c @@ -41,7 +41,7 @@ const char *built_in_field_names[BUILT_IN_FIELDS_COUNT] = { "__string__", "__subtract__", "__multiply__", - "__divide__", + "__divide__", "__new__", "__init__", "__boolean__", @@ -51,7 +51,8 @@ const char *built_in_field_names[BUILT_IN_FIELDS_COUNT] = { "__number__", "length", "__getattribute__", - "__set_attr__", + "__setattr__", + "__setitem__", "__hash__", "__repr__"}; @@ -77,9 +78,7 @@ int64_t hash_object(ArgonObject *object, ArErr *err, RuntimeState *state) { ArgonObject *hash_function = get_builtin_field_for_class( get_builtin_field(object, __class__), __hash__, object); if (!hash_function) { - *err = create_err(err->line, err->column, err->length, err->path, - "Hash Error", "objects class has no __hash__ method"); - return 0; + return (int64_t)object; } ArgonObject *hash_result = argon_call(hash_function, 0, NULL, err, state); if (hash_result->type != TYPE_NUMBER || diff --git a/src/runtime/runtime.c b/src/runtime/runtime.c index d1be7d2..6b5382f 100644 --- a/src/runtime/runtime.c +++ b/src/runtime/runtime.c @@ -285,12 +285,12 @@ ArgonObject *BASE_CLASS___init__(size_t argc, ArgonObject **argv, ArErr *err, return ARGON_NULL; } -ArgonObject *BASE_CLASS___set_attr__(size_t argc, ArgonObject **argv, ArErr *err, +ArgonObject *BASE_CLASS___setattr__(size_t argc, ArgonObject **argv, ArErr *err, RuntimeState *state) { (void)state; if (argc != 3) { *err = create_err(0, 0, 0, "", "Runtime Error", - "__set_attr__ expects 3 argument, got %" PRIu64, argc); + "__setattr__ expects 3 argument, got %" PRIu64, argc); } if (!argv[1]->value.as_str->hash) argv[1]->value.as_str->hash = @@ -691,13 +691,14 @@ void bootstrap_types() { create_argon_native_function("__getattribute__", BASE_CLASS___getattribute__)); add_builtin_field( - BASE_CLASS, __set_attr__, - create_argon_native_function("__set_attr__", BASE_CLASS___set_attr__)); + BASE_CLASS, __setattr__, + create_argon_native_function("__setattr__", BASE_CLASS___setattr__)); create_ARGON_DICTIONARY_TYPE(); create_ARGON_NUMBER_TYPE(); } -void add_to_hashmap(struct hashmap_GC *hashmap, char *name, ArgonObject *value) { +void add_to_hashmap(struct hashmap_GC *hashmap, char *name, + ArgonObject *value) { size_t length = strlen(name); uint64_t hash = siphash64_bytes(name, length, siphash_key); ArgonObject *key = new_string_object(name, length, 0, hash); @@ -719,51 +720,53 @@ void bootstrap_globals() { struct hashmap_GC *argon_term = createHashmap_GC(); add_to_hashmap(argon_term, "log", - create_argon_native_function("log", term_log)); + create_argon_native_function("log", term_log)); add_to_scope(Global_Scope, "term", create_dictionary(argon_term)); - struct hashmap_GC *environment_variables = createHashmap_GC(); - #if defined(_WIN32) - // Windows: use WinAPI - LPCH env = GetEnvironmentStringsA(); - if (!env) return; +#if defined(_WIN32) + // Windows: use WinAPI + LPCH env = GetEnvironmentStringsA(); + if (!env) + return; - for (LPCH var = env; *var; var += strlen(var) + 1) { - // Each string is like "KEY=VALUE" - const char *equals = strchr(var, '='); - if (equals) { - size_t key_len = equals - var; - char key[256]; - if (key_len >= sizeof(key)) - key_len = sizeof(key) - 1; - strncpy(key, var, key_len); - key[key_len] = '\0'; + for (LPCH var = env; *var; var += strlen(var) + 1) { + // Each string is like "KEY=VALUE" + const char *equals = strchr(var, '='); + if (equals) { + size_t key_len = equals - var; + char key[256]; + if (key_len >= sizeof(key)) + key_len = sizeof(key) - 1; + strncpy(key, var, key_len); + key[key_len] = '\0'; - const char *value = getenv(key); - add_to_hashmap(environment_variables, key, - value?new_string_object_null_terminated((char *)value):ARGON_NULL); - } + const char *value = getenv(key); + add_to_hashmap(environment_variables, key, + value ? new_string_object_null_terminated((char *)value) + : ARGON_NULL); } + } - FreeEnvironmentStringsA(env); + FreeEnvironmentStringsA(env); #else - // POSIX systems: use environ - for (char **env = environ; *env != NULL; env++) { - const char *equals = strchr(*env, '='); - if (equals) { - size_t key_len = equals - *env; - char key[256]; - if (key_len >= sizeof(key)) - key_len = sizeof(key) - 1; - strncpy(key, *env, key_len); - key[key_len] = '\0'; + // POSIX systems: use environ + for (char **env = environ; *env != NULL; env++) { + const char *equals = strchr(*env, '='); + if (equals) { + size_t key_len = equals - *env; + char key[256]; + if (key_len >= sizeof(key)) + key_len = sizeof(key) - 1; + strncpy(key, *env, key_len); + key[key_len] = '\0'; - const char *value = getenv(key); - add_to_hashmap(environment_variables, key, - value?new_string_object_null_terminated((char *)value):ARGON_NULL); - } + const char *value = getenv(key); + add_to_hashmap(environment_variables, key, + value ? new_string_object_null_terminated((char *)value) + : ARGON_NULL); } + } #endif add_to_scope(Global_Scope, "env", create_dictionary(environment_variables)); @@ -885,7 +888,9 @@ void runtime(Translated _translated, RuntimeState _state, Stack *stack, [OP_MULTIPLICATION] = &&DO_MULTIPLICATION, [OP_DIVISION] = &&DO_DIVISION, [OP_NOT] = &&DO_NOT, - [OP_LOAD_SETATTR_METHOD] = &&DO_LOAD_SETATTR_METHOD}; + [OP_LOAD_SETATTR_METHOD] = &&DO_LOAD_SETATTR_METHOD, + [OP_CREATE_DICTIONARY] = &&DO_CREATE_DICTIONARY, + [OP_LOAD_SETITEM_METHOD] = &&DO_LOAD_SETITEM_METHOD}; _state.head = 0; StackFrame *currentStackFrame = ar_alloc(sizeof(StackFrame)); @@ -1257,13 +1262,29 @@ void runtime(Translated _translated, RuntimeState _state, Stack *stack, } DO_LOAD_SETATTR_METHOD: { state->registers[0] = get_builtin_field_for_class( - get_builtin_field(state->registers[0], __class__), __set_attr__, + get_builtin_field(state->registers[0], __class__), __setattr__, state->registers[0]); if (!state->registers[0]) { *err = create_err( state->source_location.line, state->source_location.column, state->source_location.length, state->path, "Runtime Error", - "unable to get __set_attr__ from objects class"); + "unable to get __setattr__ from objects class"); + } + continue; + } + DO_CREATE_DICTIONARY: { + state->registers[0] = create_dictionary(createHashmap_GC()); + continue; + } + DO_LOAD_SETITEM_METHOD: { + state->registers[0] = get_builtin_field_for_class( + get_builtin_field(state->registers[0], __class__), __setitem__, + state->registers[0]); + if (!state->registers[0]) { + *err = create_err( + state->source_location.line, state->source_location.column, + state->source_location.length, state->path, "Runtime Error", + "unable to get __setitem__ from objects class"); } continue; } diff --git a/src/translator/bytecode_spec.md b/src/translator/bytecode_spec.md index 9fda22d..3169678 100644 --- a/src/translator/bytecode_spec.md +++ b/src/translator/bytecode_spec.md @@ -122,11 +122,11 @@ sets the source location onto the runtime ## OP_LOAD_GETATTRIBUTE_METHOD -loads the \_\_getattribute\_\_ method from the objects class in register 1 and put it into register 1 +loads the \_\_getattribute\_\_ method from the objects class in register 0 and put it into register 0 ## OP_LOAD_BOOL -loads a boolean into register 1 +loads a boolean into register 0 1. byte representing true or false (1 or 0) * @@ -187,4 +187,12 @@ inverts the boolean value in register 0. ## OP_LOAD_SETATTR_METHOD -loads the \_\_setattr\_\_ method from the objects class in register 1 and put it into register 1 \ No newline at end of file +loads the \_\_setattr\_\_ method from the objects class in register 0 and put it into register 0 + +## OP_CREATE_DICTIONARY + +create a dictionary object into register 0. + +## OP_LOAD_SETITEM_METHOD + +loads the \_\_setitem\_\_ method from the objects class in register 0 and put it into register 0 \ No newline at end of file diff --git a/src/translator/translator.c b/src/translator/translator.c index efbea54..bd4cc2f 100644 --- a/src/translator/translator.c +++ b/src/translator/translator.c @@ -6,6 +6,7 @@ #include "translator.h" #include "../hash_data/hash_data.h" +#include "../parser/dictionary/dictionary.h" #include "../parser/not/not.h" #include "access/access.h" #include "assignment/assignment.h" @@ -176,6 +177,66 @@ size_t translate_parsed(Translated *translated, ParsedValue *parsedValue, push_instruction_byte(translated, OP_NOT); return first; } + case AST_DICTIONARY: { + DArray *dictionaryDarray = parsedValue->data; + + size_t first = push_instruction_byte(translated, OP_CREATE_DICTIONARY); + uint8_t dictionaryRegister = translated->registerAssignment++; + + push_instruction_byte(translated, OP_COPY_TO_REGISTER); + push_instruction_byte(translated, 0); + push_instruction_byte(translated, dictionaryRegister); + + push_instruction_byte(translated, OP_LOAD_SETITEM_METHOD); + uint8_t setitemRegister = translated->registerAssignment++; + + push_instruction_byte(translated, OP_COPY_TO_REGISTER); + push_instruction_byte(translated, 0); + push_instruction_byte(translated, setitemRegister); + + for (size_t i = 0; i < dictionaryDarray->size; i++) { + ParsedDictionaryEntry *entry = darray_get(dictionaryDarray, i); + if (i != 0) { + push_instruction_byte(translated, OP_COPY_TO_REGISTER); + push_instruction_byte(translated, setitemRegister); + push_instruction_byte(translated, 0); + } + push_instruction_byte(translated, OP_INIT_CALL); + push_instruction_code(translated, 2); + + translate_parsed(translated, entry->key, err); + if (err->exists) + return first; + + push_instruction_byte(translated, OP_INSERT_ARG); + push_instruction_code(translated, 0); + + translate_parsed(translated, entry->value, err); + if (err->exists) + return first; + + push_instruction_byte(translated, OP_INSERT_ARG); + push_instruction_code(translated, 1); + + push_instruction_byte(translated, OP_CALL); + } + + push_instruction_byte(translated, OP_COPY_TO_REGISTER); + push_instruction_byte(translated, dictionaryRegister); + push_instruction_byte(translated, 0); + + push_instruction_byte(translated, OP_LOAD_NULL); + push_instruction_byte(translated, dictionaryRegister); + + push_instruction_byte(translated, OP_LOAD_NULL); + push_instruction_byte(translated, setitemRegister); + + translated->registerAssignment-=2; + return first; + } + default: + fprintf(stderr, "panic: undefined translation\n"); + exit(EXIT_FAILURE); } return 0; } diff --git a/src/translator/translator.h b/src/translator/translator.h index cdf41fe..e734008 100644 --- a/src/translator/translator.h +++ b/src/translator/translator.h @@ -40,7 +40,9 @@ typedef enum { OP_MULTIPLICATION, OP_DIVISION, OP_NOT, - OP_LOAD_SETATTR_METHOD + OP_LOAD_SETATTR_METHOD, + OP_CREATE_DICTIONARY, + OP_LOAD_SETITEM_METHOD } OperationType; void arena_resize(ConstantArena *arena, size_t new_size); diff --git a/tests/anonymous_function.ar b/tests/anonymous_function.ar index db1b060..d5540ac 100644 --- a/tests/anonymous_function.ar +++ b/tests/anonymous_function.ar @@ -1 +1,65 @@ -term.log(()=10) \ No newline at end of file +let knownContentTypes = {} +knownContentTypes["html"] = "text/html" +knownContentTypes["css"] = "text/css" +knownContentTypes["js"] = "application/javascript" +knownContentTypes["json"] = "application/json" +knownContentTypes["png"] = "image/png" +knownContentTypes["jpg"] = "image/jpeg" +knownContentTypes["jpeg"] = "image/jpeg" +knownContentTypes["gif"] = "image/gif" +knownContentTypes["svg"] = "image/svg+xml" +knownContentTypes["ico"] = "image/x-icon" +knownContentTypes["txt"] = "text/plain" +knownContentTypes["md"] = "text/markdown" +knownContentTypes["xml"] = "application/xml" +knownContentTypes["pdf"] = "application/pdf" +knownContentTypes["zip"] = "application/zip" +knownContentTypes["gz"] = "application/gzip" +knownContentTypes["tar"] = "application/x-tar" +knownContentTypes["ogg"] = "audio/ogg" +knownContentTypes["mp3"] = "audio/mpeg" +knownContentTypes["mp4"] = "video/mp4" +knownContentTypes["webm"] = "video/webm" +knownContentTypes["webp"] = "image/webp" +knownContentTypes["woff"] = "font/woff" +knownContentTypes["woff2"] = "font/woff2" +knownContentTypes["ttf"] = "font/ttf" +knownContentTypes["otf"] = "font/otf" +knownContentTypes["eot"] = "application/vnd.ms-fontobject" +knownContentTypes["sfnt"] = "application/font-sfnt" +knownContentTypes["wasm"] = "application/wasm" +knownContentTypes["csv"] = "text/csv" +knownContentTypes["tsv"] = "text/tab-separated-values" +knownContentTypes["rtf"] = "application/rtf" +knownContentTypes["7z"] = "application/x-7z-compressed" +knownContentTypes["rar"] = "application/x-rar-compressed" +knownContentTypes["bz"] = "application/x-bzip" +knownContentTypes["bz2"] = "application/x-bzip2" +knownContentTypes["xz"] = "application/x-xz" +knownContentTypes["exe"] = "application/x-msdownload" +knownContentTypes["swf"] = "application/x-shockwave-flash" +knownContentTypes["flv"] = "video/x-flv" +knownContentTypes["wmv"] = "video/x-ms-wmv" +knownContentTypes["avi"] = "video/x-msvideo" +knownContentTypes["mpg"] = "video/mpeg" +knownContentTypes["mpeg"] = "video/mpeg" +knownContentTypes["mov"] = "video/quicktime" +knownContentTypes["weba"] = "audio/webm" +knownContentTypes["wav"] = "audio/wav" +knownContentTypes["flac"] = "audio/flac" +knownContentTypes["midi"] = "audio/midi" +knownContentTypes["mid"] = "audio/midi" +knownContentTypes["m4a"] = "audio/m4a" +knownContentTypes["m4v"] = "video/m4v" +knownContentTypes["3gp"] = "video/3gpp" +knownContentTypes["3g2"] = "video/3gpp2" +knownContentTypes["ogv"] = "video/ogg" +knownContentTypes["m3u8"] = "application/vnd.apple.mpegurl" +knownContentTypes["ts"] = "video/mp2t" +knownContentTypes["flv"] = "video/x-flv" +knownContentTypes["wmv"] = "video/x-ms-wmv" + +term.log(()=10) +term.log((x)=10) +term.log((x,y)=10) +term.log((x,y,z)=10) \ No newline at end of file diff --git a/tests/diff.ar b/tests/diff.ar new file mode 100644 index 0000000..0e5d3ec --- /dev/null +++ b/tests/diff.ar @@ -0,0 +1,16 @@ +let h = 1e-1000 +let diff(f) = (x) = (f(x + h) - f(x)) / h + + +let f(x) = x*x*x*x*x*x*x*x*x*x+2*x*x*x*x*x*x*x*x*x+3*x*x*x*x*x*x*x*x+4*x*x*x*x*x*x*x+5*x*x*x*x*x*x+6*x*x*x*x*x+7*x*x*x*x+8*x*x*x+9*x*x+10*x+11 +let x = 100 +let d = 0 + +do + while (true) do + let n = f(x) + term.log("f"+string(d)+"("+string(x)+") = "+string(n)) + if (n) do + f = diff(f) + d = d + 1 + else return \ No newline at end of file diff --git a/tests/iteration-test.ar b/tests/iteration-test.ar index 4dd03d1..7d2094d 100644 --- a/tests/iteration-test.ar +++ b/tests/iteration-test.ar @@ -1,4 +1,4 @@ term.log(global) -let i = 1e8 +let i = 1e7 while (i) do i=i-1 \ No newline at end of file diff --git a/tests/number-memory-leak.ar b/tests/number-memory-leak.ar index f374c8c..c23b132 100644 --- a/tests/number-memory-leak.ar +++ b/tests/number-memory-leak.ar @@ -1,6 +1,6 @@ let i = 10 let x = 1 +let n = 1e1000000 * 1e1000000 * 1e1000000 * 1e1000000 * 1e1000000 * 1e1000000 * 1e1000000 * 1e1000000 * 1e1000000 * 1e1000000 * 1e1000000 * 1e1000000 * 1e1000000 * 1e1000000 * 1e1000000 * 1e1000000 * 1e1000000 * 1e1000000 * 1e1000000 * 1e1000000 * 1e1000000 * 1e1000000 * 1e1000000 * 1e1000000 while (i) do - x = x * 1e100000000 - term.log(i=i-1) -term.log(x) \ No newline at end of file + x = x*n + term.log(i=i-1) \ No newline at end of file