diff --git a/.gitignore b/.gitignore index 2c7041a..987f111 100644 --- a/.gitignore +++ b/.gitignore @@ -64,4 +64,5 @@ build *.yy.c *.yy.h -__arcache__ \ No newline at end of file +__arcache__ +argon_modules \ No newline at end of file diff --git a/argon-package.json b/argon-package.json new file mode 100644 index 0000000..c4ed7b0 --- /dev/null +++ b/argon-package.json @@ -0,0 +1,4 @@ +{ + "name": "carbon", + "version": "1.0.0" +} \ No newline at end of file diff --git a/iso-lock.json b/iso-lock.json new file mode 100644 index 0000000..446d6b3 --- /dev/null +++ b/iso-lock.json @@ -0,0 +1 @@ +[{"Name":"http.ar","Version":"1.1.7","URL":"https://isotope.wbell.dev/isotope-download?name=http.ar\u0026version=1.1.7","Remote":"isotope.wbell.dev"}] diff --git a/src/arobject.h b/src/arobject.h index 3083221..2913ace 100644 --- a/src/arobject.h +++ b/src/arobject.h @@ -74,7 +74,6 @@ struct ArgonObject { struct hashmap_GC *dict; union { mpq_t *as_number; - bool as_bool; struct string_struct as_str; native_fn native_fn; struct argon_function_struct argon_fn; diff --git a/src/parser/literals/literals.c b/src/parser/literals/literals.c index a5dbd80..3796d45 100644 --- a/src/parser/literals/literals.c +++ b/src/parser/literals/literals.c @@ -9,20 +9,17 @@ #include #include "../../memory.h" -static bool true_value = true; -static bool false_value = false; - ParsedValue * parse_true(){ ParsedValue * parsedValue = checked_malloc(sizeof(ParsedValue)); parsedValue->type = AST_BOOLEAN; - parsedValue->data = &true_value; + parsedValue->data = (void*)true; return parsedValue; }; ParsedValue * parse_false(){ ParsedValue * parsedValue = checked_malloc(sizeof(ParsedValue)); parsedValue->type = AST_BOOLEAN; - parsedValue->data = &false_value; + parsedValue->data = (void*)false; return parsedValue; }; diff --git a/src/runtime/objects/number/number.c b/src/runtime/objects/number/number.c index e4c3acb..1f90ad3 100644 --- a/src/runtime/objects/number/number.c +++ b/src/runtime/objects/number/number.c @@ -84,18 +84,43 @@ ArgonObject *ARGON_NUMBER_TYPE___add__(size_t argc, ArgonObject **argv, "__add__ expects 2 arguments, got %" PRIu64, argc); return ARGON_NULL; } + if (argv[1]->type != TYPE_NUMBER) { + ArgonObject *type_name = get_field_for_class( + get_field(argv[1], "__class__", false, false), "__name__", argv[1]); + *err = create_err(0, 0, 0, "", "Runtime Error", + "__add__ cannot perform addition between a number and %.*s", + type_name->value.as_str.length, + type_name->value.as_str.data); + return ARGON_NULL; + } + mpq_t r; + mpq_init(r); + mpq_add(r, *argv[0]->value.as_number, *argv[1]->value.as_number); + ArgonObject *result = new_number_object(r); + mpq_clear(r); + return result; +} + +ArgonObject *ARGON_NUMBER_TYPE___subtract__(size_t argc, ArgonObject **argv, + ArErr *err, RuntimeState *state) { + (void)state; + if (argc != 2) { + *err = create_err(0, 0, 0, "", "Runtime Error", + "__subtract__ expects 2 arguments, got %" PRIu64, argc); + return ARGON_NULL; + } mpq_t r; mpq_init(r); if (argv[1]->type != TYPE_NUMBER) { ArgonObject *type_name = get_field_for_class( get_field(argv[1], "__class__", false, false), "__name__", argv[1]); *err = create_err(0, 0, 0, "", "Runtime Error", - "__add__ cannot perform addition between number and %.*s", + "__subtract__ cannot perform subtraction between number and %.*s", type_name->value.as_str.length, type_name->value.as_str.data); return ARGON_NULL; } - mpq_add(r, *argv[0]->value.as_number, *argv[1]->value.as_number); + mpq_sub(r, *argv[0]->value.as_number, *argv[1]->value.as_number); ArgonObject *result = new_number_object(r); mpq_clear(r); return result; @@ -270,6 +295,9 @@ void create_ARGON_NUMBER_TYPE() { add_field(ARGON_NUMBER_TYPE, "__add__", create_argon_native_function("__add__", ARGON_NUMBER_TYPE___add__)); + add_field(ARGON_NUMBER_TYPE, "__subtract__", + create_argon_native_function("__subtract__", + ARGON_NUMBER_TYPE___subtract__)); } void mpz_init_gc_managed(mpz_t z, size_t limbs_count) { diff --git a/src/runtime/runtime.c b/src/runtime/runtime.c index fe26181..a60daa4 100644 --- a/src/runtime/runtime.c +++ b/src/runtime/runtime.c @@ -35,6 +35,12 @@ ArgonObject *ARGON_METHOD_TYPE; Stack *Global_Scope = NULL; ArgonObject *ACCESS_FUNCTION; ArgonObject *ADDITION_FUNCTION; +ArgonObject *SUBTRACTION_FUNCTION; +ArgonObject *MULTIPLY_FUNCTION; +ArgonObject *DIVIDE_FUNCTION; +ArgonObject *POWER_FUNCTION; +ArgonObject *MODULO_FUNCTION; +ArgonObject *FLOORDIV_FUNCTION; ArgonObject *ARGON_ADDITION_FUNCTION(size_t argc, ArgonObject **argv, ArErr *err, RuntimeState *state) { @@ -60,6 +66,31 @@ ArgonObject *ARGON_ADDITION_FUNCTION(size_t argc, ArgonObject **argv, return output; } +ArgonObject *ARGON_SUBTRACTION_FUNCTION(size_t argc, ArgonObject **argv, + ArErr *err, RuntimeState *state) { + if (argc < 1) { + *err = create_err(0, 0, 0, "", "Runtime Error", + "add expects at least 1 argument, got %" PRIu64, argc); + return ARGON_NULL; + } + ArgonObject *output = argv[0]; + for (size_t i = 1; i < argc; i++) { + ArgonObject *__subtract__ = get_field_for_class( + get_field(output, "__class__", false, false), "__subtract__", output); + if (!__subtract__) { + ArgonObject *cls___name__ = get_field(output, "__name__", true, false); + *err = create_err(0, 0, 0, "", "Runtime Error", + "Object '%.*s' is missing __subtract__ method", + (int)cls___name__->value.as_str.length, + cls___name__->value.as_str.data); + return ARGON_NULL; + } + output = + argon_call(__subtract__, 1, (ArgonObject *[]){argv[i]}, err, state); + } + return output; +} + ArgonObject *ARGON_TYPE_TYPE___call__(size_t argc, ArgonObject **argv, ArErr *err, RuntimeState *state) { (void)state; @@ -244,6 +275,53 @@ ArgonObject *ARGON_BOOL_TYPE___new__(size_t argc, ArgonObject **argv, return ARGON_NULL; } +ArgonObject *ARGON_STRING_TYPE___add__(size_t argc, ArgonObject **argv, + ArErr *err, RuntimeState *state) { + (void)state; + if (argc != 2) { + *err = create_err(0, 0, 0, "", "Runtime Error", + "__add__ expects 2 arguments, got %" PRIu64, argc); + return ARGON_NULL; + } + if (argv[1]->type != TYPE_STRING) { + ArgonObject *type_name = get_field_for_class( + get_field(argv[1], "__class__", false, false), "__name__", argv[1]); + *err = create_err(0, 0, 0, "", "Runtime Error", + "__add__ cannot perform concatenation between a string and %.*s", + type_name->value.as_str.length, + type_name->value.as_str.data); + return ARGON_NULL; + } + size_t length = argv[0]->value.as_str.length+argv[1]->value.as_str.length; + char*concat = malloc(length); + memcpy(concat,argv[0]->value.as_str.data, argv[0]->value.as_str.length); + memcpy(concat+argv[0]->value.as_str.length,argv[1]->value.as_str.data, argv[1]->value.as_str.length); + ArgonObject* object = new_string_object(concat, length); + free(concat); + return object; +} + +ArgonObject *ARGON_BOOL_TYPE___string__(size_t argc, ArgonObject **argv, + ArErr *err, RuntimeState *state) { + if (argc != 1) { + *err = create_err(0, 0, 0, "", "Runtime Error", + "__string__ expects 1 arguments, got %" PRIu64, argc); + return ARGON_NULL; + } + return new_string_object_null_terminated(argv[0] == ARGON_TRUE ? "true" + : "false"); +} + +ArgonObject *ARGON_BOOL_TYPE___number__(size_t argc, ArgonObject **argv, + ArErr *err, RuntimeState *state) { + if (argc != 1) { + *err = create_err(0, 0, 0, "", "Runtime Error", + "__number__ expects 1 arguments, got %" PRIu64, argc); + return ARGON_NULL; + } + return new_number_object_from_long(argv[0] == ARGON_TRUE, 1); +} + ArgonObject *ARGON_STRING_TYPE___string__(size_t argc, ArgonObject **argv, ArErr *err, RuntimeState *state) { (void)state; @@ -388,6 +466,9 @@ void bootstrap_types() { add_field( ARGON_STRING_TYPE, "__init__", create_argon_native_function("__init__", ARGON_STRING_TYPE___init__)); + add_field( + ARGON_STRING_TYPE, "__add__", + create_argon_native_function("__add__", ARGON_STRING_TYPE___add__)); add_field( ARGON_STRING_TYPE, "__number__", create_argon_native_function("__number__", ARGON_STRING_TYPE___number__)); @@ -414,10 +495,18 @@ void bootstrap_types() { add_field( BASE_CLASS, "__boolean__", create_argon_native_function("__boolean__", BASE_CLASS___boolean__)); + add_field( + ARGON_BOOL_TYPE, "__string__", + create_argon_native_function("__string__", ARGON_BOOL_TYPE___string__)); + add_field( + ARGON_BOOL_TYPE, "__number__", + create_argon_native_function("__number__", ARGON_BOOL_TYPE___number__)); ACCESS_FUNCTION = create_argon_native_function("__get_attr__", ARGON_TYPE_TYPE___get_attr__); ADDITION_FUNCTION = create_argon_native_function("add", ARGON_ADDITION_FUNCTION); + SUBTRACTION_FUNCTION = + create_argon_native_function("subtract", ARGON_SUBTRACTION_FUNCTION); add_field(BASE_CLASS, "__get_attr__", ACCESS_FUNCTION); } @@ -435,6 +524,7 @@ void bootstrap_globals() { add_to_scope(Global_Scope, "boolean", ARGON_BOOL_TYPE); add_to_scope(Global_Scope, "number", ARGON_NUMBER_TYPE); add_to_scope(Global_Scope, "add", ADDITION_FUNCTION); + add_to_scope(Global_Scope, "subtract", SUBTRACTION_FUNCTION); ArgonObject *argon_term = new_object(); add_field(argon_term, "__init__", ARGON_NULL); @@ -627,6 +717,9 @@ ArErr run_instruction(Translated *translated, RuntimeState *state, case OP_LOAD_ADDITION_FUNCTION: state->registers[0] = ADDITION_FUNCTION; break; + case OP_LOAD_SUBTRACTION_FUNCTION: + state->registers[0] = SUBTRACTION_FUNCTION; + break; default: return create_err(0, 0, 0, NULL, "Runtime Error", "Invalid Opcode %#x", opcode); diff --git a/src/translator/bytecode_spec.md b/src/translator/bytecode_spec.md index 580df2d..ecebad2 100644 --- a/src/translator/bytecode_spec.md +++ b/src/translator/bytecode_spec.md @@ -131,4 +131,8 @@ loads a mpq_t number into memory ## OP_LOAD_ADDITION_FUNCTION -loads the addition function into register 1 \ No newline at end of file +loads the addition function into register 1 + +## OP_LOAD_SUBTRACTION_FUNCTION + +loads the subtraction function into register 1 \ No newline at end of file diff --git a/src/translator/operation/operation.c b/src/translator/operation/operation.c index a301442..0c4e3ad 100644 --- a/src/translator/operation/operation.c +++ b/src/translator/operation/operation.c @@ -8,18 +8,20 @@ #include size_t translate_operation(Translated *translated, ParsedOperation *operation, - ArErr *err) { + ArErr *err) { set_registers(translated, 1); uint64_t first; switch (operation->operation) { - case TOKEN_PLUS:; - first = push_instruction_byte(translated, OP_LOAD_ADDITION_FUNCTION); - break; - default: - *err = create_err(operation->line, operation->column, - operation->length, translated->path, "Syntax Error", - "unknown operation"); - return 0; + case TOKEN_PLUS:; + first = push_instruction_byte(translated, OP_LOAD_ADDITION_FUNCTION); + break; + case TOKEN_MINUS: + first = push_instruction_byte(translated, OP_LOAD_SUBTRACTION_FUNCTION); + break; + default: + *err = create_err(operation->line, operation->column, operation->length, + translated->path, "Syntax Error", "unknown operation"); + return 0; } push_instruction_byte(translated, OP_INIT_CALL); push_instruction_code(translated, operation->to_operate_on.size); diff --git a/src/translator/translator.c b/src/translator/translator.c index 0e76a3c..524e05d 100644 --- a/src/translator/translator.c +++ b/src/translator/translator.c @@ -135,6 +135,11 @@ size_t translate_parsed(Translated *translated, ParsedValue *parsedValue, size_t output = push_instruction_byte(translated, OP_LOAD_NULL); push_instruction_byte(translated, 0); return output; + case AST_BOOLEAN: + set_registers(translated, 1); + output = push_instruction_byte(translated, OP_LOAD_BOOL); + push_instruction_byte(translated, (bool)parsedValue->data); + return output; case AST_FUNCTION: return translate_parsed_function(translated, (ParsedFunction *)parsedValue->data, err); diff --git a/src/translator/translator.h b/src/translator/translator.h index cd58639..d7134b8 100644 --- a/src/translator/translator.h +++ b/src/translator/translator.h @@ -32,7 +32,8 @@ typedef enum { OP_LOAD_ACCESS_FUNCTION, OP_LOAD_BOOL, OP_LOAD_NUMBER, - OP_LOAD_ADDITION_FUNCTION + OP_LOAD_ADDITION_FUNCTION, + OP_LOAD_SUBTRACTION_FUNCTION } OperationType; void arena_resize(ConstantArena *arena, size_t new_size); diff --git a/testing.ar b/testing.ar index 3a11dae..158c203 100644 --- a/testing.ar +++ b/testing.ar @@ -1 +1 @@ -term.log(1984+1) \ No newline at end of file +term.log("hello "+"world") \ No newline at end of file