start working on supporting operations

This commit is contained in:
William Bell
2025-08-14 04:51:11 +01:00
parent d4528e44f6
commit 340843c99c
15 changed files with 393 additions and 67 deletions

View File

@@ -97,7 +97,7 @@ int yywrap(void * unused_param) {
return TOKEN_STRING; return TOKEN_STRING;
} }
((([0-9]+(\.[0-9]+)?)|(\.[0-9]+))(e((\-|\+)?([0-9]+)))?) { ((([0-9]+(\.[0-9]+)?)|(\.[0-9]+))((e|E)((\-|\+)?([0-9]+)))?) {
return TOKEN_NUMBER; return TOKEN_NUMBER;
} }
@@ -113,7 +113,7 @@ int yywrap(void * unused_param) {
#[^\n]* { /* skip comment */ } #[^\n]* { /* skip comment */ }
.|((([0-9]+(\.[0-9]+)?)|(\.[0-9]+))(e((\-|\+)?([0-9]+(\.[0-9]+)?)))?) { .|((([0-9]+(\.[0-9]+)?)|(\.[0-9]+))((e|E)((\-|\+)?([0-9]+(\.[0-9]+)?)))?) {
return TOKEN_INVALID; return TOKEN_INVALID;
} }
%% %%

View File

@@ -24,7 +24,7 @@ int parse_exponent(const char *exp_str, long *exp_val) {
return 0; return 0;
} }
int mpq_set_decimal_str_exp(mpq_t r, const char *str) { int mpq_set_decimal_str_exp(mpq_t r, const char *str, size_t len) {
// Skip leading whitespace // Skip leading whitespace
while (isspace(*str)) while (isspace(*str))
str++; str++;
@@ -39,11 +39,11 @@ int mpq_set_decimal_str_exp(mpq_t r, const char *str) {
} }
// Copy input to a buffer for manipulation // Copy input to a buffer for manipulation
size_t len = strlen(str);
char *buf = malloc(len + 1); char *buf = malloc(len + 1);
if (!buf) if (!buf)
return -1; return -1;
strcpy(buf, str); memcpy(buf, str, len);
buf[len] = '\0';
// Find 'e' or 'E' // Find 'e' or 'E'
char *e_ptr = strchr(buf, 'e'); char *e_ptr = strchr(buf, 'e');
@@ -178,7 +178,7 @@ ParsedValueReturn parse_number(Token *token, char *path) {
parsedValue->type = AST_NUMBER; parsedValue->type = AST_NUMBER;
mpq_t *r_ptr = malloc(sizeof(mpq_t)); mpq_t *r_ptr = malloc(sizeof(mpq_t));
mpq_init(*r_ptr); mpq_init(*r_ptr);
int err = mpq_set_decimal_str_exp(*r_ptr, token->value); int err = mpq_set_decimal_str_exp(*r_ptr, token->value, token->length);
if (err) { if (err) {
free_parsed(parsedValue); free_parsed(parsedValue);
free(parsedValue); free(parsedValue);

View File

@@ -12,4 +12,6 @@
// Function declaration for parsing an identifier // Function declaration for parsing an identifier
ParsedValueReturn parse_number(Token *token, char*path); ParsedValueReturn parse_number(Token *token, char*path);
int mpq_set_decimal_str_exp(mpq_t r, const char *str, size_t len);
#endif // NUMBER_H #endif // NUMBER_H

View File

@@ -12,18 +12,22 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
struct operation {};
ParsedValue convert_to_operation(DArray *to_operate_on, DArray *operations) { ParsedValue convert_to_operation(DArray *to_operate_on, DArray *operations) {
if (to_operate_on->size == 1) { if (to_operate_on->size == 1) {
return *((ParsedValue *)darray_get(to_operate_on, 0)); return *((ParsedValue *)darray_get(to_operate_on, 0));
} }
ArTokenType operation = 0; ArTokenType operation_type = 0;
Token operation = {};
DArray positions; DArray positions;
for (size_t i = 0; i < operations->size; i++) { for (size_t i = 0; i < operations->size; i++) {
ArTokenType *current_operation = darray_get(operations, i); Token *current_operation = darray_get(operations, i);
if (operation < *current_operation) { if (operation_type < current_operation->type) {
if (operation != 0) { if (operation_type != 0) {
darray_free(&positions, NULL); darray_free(&positions, NULL);
} }
operation_type = current_operation->type;
operation = *current_operation; operation = *current_operation;
darray_init(&positions, sizeof(size_t)); darray_init(&positions, sizeof(size_t));
} }
@@ -33,7 +37,10 @@ ParsedValue convert_to_operation(DArray *to_operate_on, DArray *operations) {
parsedValue.type = AST_OPERATION; parsedValue.type = AST_OPERATION;
ParsedOperation *operationStruct = checked_malloc(sizeof(ParsedOperation)); ParsedOperation *operationStruct = checked_malloc(sizeof(ParsedOperation));
parsedValue.data = operationStruct; parsedValue.data = operationStruct;
operationStruct->operation = operation; operationStruct->operation = operation_type;
operationStruct->line = operation.line;
operationStruct->column = operation.column;
operationStruct->length = operation.length;
darray_init(&operationStruct->to_operate_on, sizeof(ParsedValue)); darray_init(&operationStruct->to_operate_on, sizeof(ParsedValue));
size_t last_position = 0; size_t last_position = 0;
size_t to_operate_on_last_position = 0; size_t to_operate_on_last_position = 0;
@@ -68,7 +75,7 @@ ParsedValueReturn parse_operations(char *file, DArray *tokens, size_t *index,
free(first_parsed_value); free(first_parsed_value);
DArray operations; DArray operations;
darray_init(&operations, sizeof(ArTokenType)); darray_init(&operations, sizeof(Token));
while (tokens->size > *index) { while (tokens->size > *index) {
bool to_break = false; bool to_break = false;
@@ -81,7 +88,7 @@ ParsedValueReturn parse_operations(char *file, DArray *tokens, size_t *index,
} }
if (to_break) if (to_break)
break; break;
darray_push(&operations, &token->type); darray_push(&operations, token);
(*index)++; (*index)++;
ArErr err = error_if_finished(file, tokens, index); ArErr err = error_if_finished(file, tokens, index);
if (err.exists) { if (err.exists) {

View File

@@ -12,6 +12,9 @@
typedef struct { typedef struct {
ArTokenType operation; ArTokenType operation;
DArray to_operate_on; // ParsedValue[] DArray to_operate_on; // ParsedValue[]
size_t line;
size_t column;
size_t length;
} ParsedOperation; } ParsedOperation;
ParsedValueReturn parse_operations(char *file, DArray *tokens, size_t *index, ParsedValueReturn parse_operations(char *file, DArray *tokens, size_t *index,

View File

@@ -14,6 +14,8 @@
ArgonObject *ARGON_NUMBER_TYPE; ArgonObject *ARGON_NUMBER_TYPE;
#include "../../call/call.h"
#include "../literals/literals.h"
#include <gmp.h> #include <gmp.h>
#include <inttypes.h> #include <inttypes.h>
#include <stdio.h> #include <stdio.h>
@@ -23,6 +25,82 @@ ArgonObject *ARGON_NUMBER_TYPE;
/* change SIGNIFICANT_DIGITS to taste (15 mimics double-ish behaviour) */ /* change SIGNIFICANT_DIGITS to taste (15 mimics double-ish behaviour) */
#define SIGNIFICANT_DIGITS 15 #define SIGNIFICANT_DIGITS 15
ArgonObject *ARGON_NUMBER_TYPE___new__(size_t argc, ArgonObject **argv,
ArErr *err, RuntimeState *state) {
if (argc != 2) {
*err = create_err(0, 0, 0, "", "Runtime Error",
"__new__ expects 2 arguments, got %" PRIu64, argc);
return ARGON_NULL;
}
ArgonObject *self = argv[0];
ArgonObject *object = argv[1];
self->type = TYPE_STRING;
ArgonObject *boolean_convert_method = get_field_for_class(
get_field(object, "__class__", false, false), "__number__", object);
if (boolean_convert_method) {
ArgonObject *boolean_object =
argon_call(boolean_convert_method, 0, NULL, err, state);
if (err->exists)
return ARGON_NULL;
return boolean_object;
}
ArgonObject *type_name = get_field_for_class(
get_field(object, "__class__", false, false), "__name__", object);
*err = create_err(
0, 0, 0, "", "Runtime Error", "cannot convert type '%.*s' to number",
type_name->value.as_str.length, type_name->value.as_str.data);
return ARGON_NULL;
}
ArgonObject *ARGON_NUMBER_TYPE___number__(size_t argc, ArgonObject **argv,
ArErr *err, RuntimeState *state) {
(void)state;
if (argc != 1) {
*err = create_err(0, 0, 0, "", "Runtime Error",
"__number__ expects 1 arguments, got %" PRIu64, argc);
return ARGON_NULL;
}
return argv[0];
}
ArgonObject *ARGON_NUMBER_TYPE___boolean__(size_t argc, ArgonObject **argv,
ArErr *err, RuntimeState *state) {
(void)state;
if (argc != 1) {
*err = create_err(0, 0, 0, "", "Runtime Error",
"__boolean__ expects 1 arguments, got %" PRIu64, argc);
return ARGON_NULL;
}
return mpq_cmp_si(*argv[0]->value.as_number, 0, 1) == 0 ? ARGON_FALSE
: ARGON_TRUE;
}
ArgonObject *ARGON_NUMBER_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;
}
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",
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);
ArgonObject *result = new_number_object(r);
mpq_clear(r);
return result;
}
ArgonObject *ARGON_NUMBER_TYPE___string__(size_t argc, ArgonObject **argv, ArgonObject *ARGON_NUMBER_TYPE___string__(size_t argc, ArgonObject **argv,
ArErr *err, RuntimeState *state) { ArErr *err, RuntimeState *state) {
(void)state; (void)state;
@@ -181,6 +259,17 @@ void create_ARGON_NUMBER_TYPE() {
add_field( add_field(
ARGON_NUMBER_TYPE, "__string__", ARGON_NUMBER_TYPE, "__string__",
create_argon_native_function("__string__", ARGON_NUMBER_TYPE___string__)); create_argon_native_function("__string__", ARGON_NUMBER_TYPE___string__));
add_field(ARGON_NUMBER_TYPE, "__new__",
create_argon_native_function("__new__", ARGON_NUMBER_TYPE___new__));
add_field(
ARGON_NUMBER_TYPE, "__number__",
create_argon_native_function("__number__", ARGON_NUMBER_TYPE___number__));
add_field(ARGON_NUMBER_TYPE, "__boolean__",
create_argon_native_function("__boolean__",
ARGON_NUMBER_TYPE___boolean__));
add_field(ARGON_NUMBER_TYPE, "__add__",
create_argon_native_function("__add__",
ARGON_NUMBER_TYPE___add__));
} }
void mpz_init_gc_managed(mpz_t z, size_t limbs_count) { void mpz_init_gc_managed(mpz_t z, size_t limbs_count) {
@@ -228,12 +317,34 @@ ArgonObject *new_number_object(mpq_t number) {
return object; return object;
} }
ArgonObject *new_number_object_from_long(long n, unsigned long d) {
ArgonObject *object = new_object();
add_field(object, "__class__", ARGON_NUMBER_TYPE);
mpq_t r;
mpq_init(r);
mpq_set_si(r, n, d);
object->type = TYPE_NUMBER;
object->value.as_number = mpq_new_gc_from(r);
mpq_clear(r);
return object;
}
ArgonObject *new_number_object_from_double(double d) {
ArgonObject *object = new_object();
add_field(object, "__class__", ARGON_NUMBER_TYPE);
mpq_t r;
mpq_init(r);
mpq_set_d(r, d);
object->type = TYPE_NUMBER;
object->value.as_number = mpq_new_gc_from(r);
mpq_clear(r);
return object;
}
void load_number(Translated *translated, RuntimeState *state) { void load_number(Translated *translated, RuntimeState *state) {
uint8_t to_register = pop_byte(translated, state); uint8_t to_register = pop_byte(translated, state);
size_t num_size = pop_bytecode(translated, state); size_t num_size = pop_bytecode(translated, state);
size_t num_pos = pop_bytecode(translated, state); size_t num_pos = pop_bytecode(translated, state);
size_t den_size = pop_bytecode(translated, state);
size_t den_pos = pop_bytecode(translated, state);
mpq_t r; mpq_t r;
mpq_init(r); mpq_init(r);
mpz_t num; mpz_t num;
@@ -242,12 +353,21 @@ void load_number(Translated *translated, RuntimeState *state) {
arena_get(&translated->constants, num_pos)); arena_get(&translated->constants, num_pos));
mpq_set_num(r, num); mpq_set_num(r, num);
mpz_clear(num); mpz_clear(num);
bool is_int = pop_byte(translated, state);
if (!is_int) {
size_t den_size = pop_bytecode(translated, state);
size_t den_pos = pop_bytecode(translated, state);
mpz_t den; mpz_t den;
mpz_init(den); mpz_init(den);
mpz_import(den, den_size, 1, 1, 0, 0, mpz_import(den, den_size, 1, 1, 0, 0,
arena_get(&translated->constants, den_pos)); arena_get(&translated->constants, den_pos));
mpq_set_den(r, den); mpq_set_den(r, den);
mpz_clear(den); mpz_clear(den);
} else {
mpz_set_si(mpq_denref(r), 1);
}
state->registers[to_register] = new_number_object(r); state->registers[to_register] = new_number_object(r);
mpq_clear(r); mpq_clear(r);

View File

@@ -16,4 +16,8 @@ ArgonObject *new_number_object(mpq_t number);
void load_number(Translated *translated, RuntimeState *state); void load_number(Translated *translated, RuntimeState *state);
ArgonObject *new_number_object_from_double(double d);
ArgonObject *new_number_object_from_long(long n, unsigned long d);
#endif // RUNTIME_NUMBER_H #endif // RUNTIME_NUMBER_H

View File

@@ -7,6 +7,7 @@
#include "runtime.h" #include "runtime.h"
#include "../err.h" #include "../err.h"
#include "../hash_data/hash_data.h" #include "../hash_data/hash_data.h"
#include "../parser/number/number.h"
#include "../translator/translator.h" #include "../translator/translator.h"
#include "access/access.h" #include "access/access.h"
#include "call/call.h" #include "call/call.h"
@@ -21,6 +22,7 @@
#include "objects/type/type.h" #include "objects/type/type.h"
#include <fcntl.h> #include <fcntl.h>
#include <gc/gc.h> #include <gc/gc.h>
#include <gmp-x86_64.h>
#include <inttypes.h> #include <inttypes.h>
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
@@ -32,13 +34,39 @@
ArgonObject *ARGON_METHOD_TYPE; ArgonObject *ARGON_METHOD_TYPE;
Stack *Global_Scope = NULL; Stack *Global_Scope = NULL;
ArgonObject *ACCESS_FUNCTION; ArgonObject *ACCESS_FUNCTION;
ArgonObject *ADDITION_FUNCTION;
ArgonObject *ARGON_ADDITION_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 *__add__ = get_field_for_class(
get_field(output, "__class__", false, false), "__add__", output);
if (!__add__) {
ArgonObject *cls___name__ = get_field(output, "__name__", true, false);
*err = create_err(0, 0, 0, "", "Runtime Error",
"Object '%.*s' is missing __add__ method",
(int)cls___name__->value.as_str.length,
cls___name__->value.as_str.data);
return ARGON_NULL;
}
output = argon_call(__add__, 1, (ArgonObject *[]){argv[i]}, err, state);
}
return output;
}
ArgonObject *ARGON_TYPE_TYPE___call__(size_t argc, ArgonObject **argv, ArgonObject *ARGON_TYPE_TYPE___call__(size_t argc, ArgonObject **argv,
ArErr *err, RuntimeState *state) { ArErr *err, RuntimeState *state) {
(void)state; (void)state;
if (argc < 1) { if (argc < 1) {
*err = create_err(0, 0, 0, "", "Runtime Error", *err =
"__call__ expects at least 1 argument, got 0"); create_err(0, 0, 0, "", "Runtime Error",
"__call__ expects at least 1 argument, got %" PRIu64, argc);
return ARGON_NULL; return ARGON_NULL;
} }
ArgonObject *cls = argv[0]; ArgonObject *cls = argv[0];
@@ -85,6 +113,20 @@ ArgonObject *ARGON_TYPE_TYPE___call__(size_t argc, ArgonObject **argv,
return new_object; return new_object;
} }
ArgonObject *BASE_CLASS_address(size_t argc, ArgonObject **argv, ArErr *err,
RuntimeState *state) {
(void)state;
if (argc < 1) {
*err =
create_err(0, 0, 0, "", "Runtime Error",
"__new__ expects at least 1 argument, got %" PRIu64, argc);
return ARGON_NULL;
}
char buffer[32];
snprintf(buffer, sizeof(buffer), "%p", argv[0]);
return new_string_object_null_terminated(buffer);
}
ArgonObject *BASE_CLASS___new__(size_t argc, ArgonObject **argv, ArErr *err, ArgonObject *BASE_CLASS___new__(size_t argc, ArgonObject **argv, ArErr *err,
RuntimeState *state) { RuntimeState *state) {
(void)state; (void)state;
@@ -134,6 +176,17 @@ ArgonObject *BASE_CLASS___string__(size_t argc, ArgonObject **argv, ArErr *err,
return new_string_object_null_terminated(buffer); return new_string_object_null_terminated(buffer);
} }
ArgonObject *BASE_CLASS___boolean__(size_t argc, ArgonObject **argv, ArErr *err,
RuntimeState *state) {
(void)argv;
(void)state;
if (argc != 1) {
*err = create_err(0, 0, 0, "", "Runtime Error",
"__boolean__ expects 1 arguments, got %" PRIu64, argc);
}
return ARGON_TRUE;
}
ArgonObject *ARGON_STRING_TYPE___init__(size_t argc, ArgonObject **argv, ArgonObject *ARGON_STRING_TYPE___init__(size_t argc, ArgonObject **argv,
ArErr *err, RuntimeState *state) { ArErr *err, RuntimeState *state) {
if (argc != 2) { if (argc != 2) {
@@ -167,7 +220,7 @@ ArgonObject *ARGON_BOOL_TYPE___new__(size_t argc, ArgonObject **argv,
ArErr *err, RuntimeState *state) { ArErr *err, RuntimeState *state) {
if (argc != 2) { if (argc != 2) {
*err = create_err(0, 0, 0, "", "Runtime Error", *err = create_err(0, 0, 0, "", "Runtime Error",
"__init__ expects 2 arguments, got %" PRIu64, argc); "__new__ expects 2 arguments, got %" PRIu64, argc);
return ARGON_NULL; return ARGON_NULL;
} }
ArgonObject *self = argv[0]; ArgonObject *self = argv[0];
@@ -183,7 +236,12 @@ ArgonObject *ARGON_BOOL_TYPE___new__(size_t argc, ArgonObject **argv,
return ARGON_NULL; return ARGON_NULL;
return boolean_object; return boolean_object;
} }
return ARGON_TRUE; ArgonObject *type_name = get_field_for_class(
get_field(object, "__class__", false, false), "__name__", object);
*err = create_err(
0, 0, 0, "", "Runtime Error", "cannot convert type '%.*s' to bool",
type_name->value.as_str.length, type_name->value.as_str.data);
return ARGON_NULL;
} }
ArgonObject *ARGON_STRING_TYPE___string__(size_t argc, ArgonObject **argv, ArgonObject *ARGON_STRING_TYPE___string__(size_t argc, ArgonObject **argv,
@@ -196,6 +254,30 @@ ArgonObject *ARGON_STRING_TYPE___string__(size_t argc, ArgonObject **argv,
return argv[0]; return argv[0];
} }
ArgonObject *ARGON_STRING_TYPE___number__(size_t argc, ArgonObject **argv,
ArErr *err, RuntimeState *state) {
(void)state;
if (argc != 1) {
*err = create_err(0, 0, 0, "", "Runtime Error",
"__number__ expects 1 arguments, got %" PRIu64, argc);
return ARGON_NULL;
}
mpq_t r;
mpq_init(r);
int result = mpq_set_decimal_str_exp(r, argv[0]->value.as_str.data,
argv[0]->value.as_str.length);
if (result != 0) {
mpq_clear(r);
*err = create_err(0, 0, 0, "", "Runtime Error", "Unable to parse number",
argc);
return ARGON_NULL;
}
ArgonObject *object = new_number_object(r);
mpq_clear(r);
return object;
}
ArgonObject *ARGON_STRING_TYPE___boolean__(size_t argc, ArgonObject **argv, ArgonObject *ARGON_STRING_TYPE___boolean__(size_t argc, ArgonObject **argv,
ArErr *err, RuntimeState *state) { ArErr *err, RuntimeState *state) {
(void)state; (void)state;
@@ -216,6 +298,37 @@ ArgonObject *ARGON_BOOL_TYPE___boolean__(size_t argc, ArgonObject **argv,
return argv[0]; return argv[0];
} }
ArgonObject *ARGON_NULL_TYPE___boolean__(size_t argc, ArgonObject **argv,
ArErr *err, RuntimeState *state) {
(void)argv;
(void)state;
if (argc != 1) {
*err = create_err(0, 0, 0, "", "Runtime Error",
"__boolean__ expects 1 arguments, got %" PRIu64, argc);
}
return ARGON_FALSE;
}
ArgonObject *ARGON_NULL_TYPE___number__(size_t argc, ArgonObject **argv,
ArErr *err, RuntimeState *state) {
(void)argv;
(void)state;
if (argc != 1) {
*err = create_err(0, 0, 0, "", "Runtime Error",
"__boolean__ expects 1 arguments, got %" PRIu64, argc);
}
return new_number_object_from_long(0, 1);
}
ArgonObject *ARGON_NULL_TYPE___string__(size_t argc, ArgonObject **argv,
ArErr *err, RuntimeState *state) {
(void)argv;
(void)state;
if (argc != 1) {
*err = create_err(0, 0, 0, "", "Runtime Error",
"__boolean__ expects 1 arguments, got %" PRIu64, argc);
}
return new_string_object_null_terminated("null");
}
void bootstrap_types() { void bootstrap_types() {
BASE_CLASS = new_object(); BASE_CLASS = new_object();
ARGON_TYPE_TYPE = new_object(); ARGON_TYPE_TYPE = new_object();
@@ -264,6 +377,8 @@ void bootstrap_types() {
add_field(BASE_CLASS, "__new__", add_field(BASE_CLASS, "__new__",
create_argon_native_function("__new__", BASE_CLASS___new__)); create_argon_native_function("__new__", BASE_CLASS___new__));
add_field(BASE_CLASS, "address",
create_argon_native_function("address", BASE_CLASS_address));
add_field(BASE_CLASS, "__init__", add_field(BASE_CLASS, "__init__",
create_argon_native_function("__init__", BASE_CLASS___new__)); create_argon_native_function("__init__", BASE_CLASS___new__));
add_field(BASE_CLASS, "__string__", add_field(BASE_CLASS, "__string__",
@@ -273,6 +388,18 @@ void bootstrap_types() {
add_field( add_field(
ARGON_STRING_TYPE, "__init__", ARGON_STRING_TYPE, "__init__",
create_argon_native_function("__init__", ARGON_STRING_TYPE___init__)); create_argon_native_function("__init__", ARGON_STRING_TYPE___init__));
add_field(
ARGON_STRING_TYPE, "__number__",
create_argon_native_function("__number__", ARGON_STRING_TYPE___number__));
add_field(
ARGON_NULL_TYPE, "__boolean__",
create_argon_native_function("__boolean__", ARGON_NULL_TYPE___boolean__));
add_field(
ARGON_NULL_TYPE, "__string__",
create_argon_native_function("__string__", ARGON_NULL_TYPE___string__));
add_field(
ARGON_NULL_TYPE, "__number__",
create_argon_native_function("__number__", ARGON_NULL_TYPE___number__));
add_field( add_field(
ARGON_STRING_TYPE, "__string__", ARGON_STRING_TYPE, "__string__",
create_argon_native_function("__string__", ARGON_STRING_TYPE___string__)); create_argon_native_function("__string__", ARGON_STRING_TYPE___string__));
@@ -284,8 +411,14 @@ void bootstrap_types() {
add_field(ARGON_STRING_TYPE, "__boolean__", add_field(ARGON_STRING_TYPE, "__boolean__",
create_argon_native_function("__boolean__", create_argon_native_function("__boolean__",
ARGON_STRING_TYPE___boolean__)); ARGON_STRING_TYPE___boolean__));
ACCESS_FUNCTION = create_argon_native_function("ACCESS_FUNCTION", add_field(
BASE_CLASS, "__boolean__",
create_argon_native_function("__boolean__", BASE_CLASS___boolean__));
ACCESS_FUNCTION = create_argon_native_function("__get_attr__",
ARGON_TYPE_TYPE___get_attr__); ARGON_TYPE_TYPE___get_attr__);
ADDITION_FUNCTION =
create_argon_native_function("add", ARGON_ADDITION_FUNCTION);
add_field(BASE_CLASS, "__get_attr__", ACCESS_FUNCTION);
} }
void add_to_scope(Stack *stack, char *name, ArgonObject *value) { void add_to_scope(Stack *stack, char *name, ArgonObject *value) {
@@ -300,6 +433,8 @@ void bootstrap_globals() {
add_to_scope(Global_Scope, "string", ARGON_STRING_TYPE); add_to_scope(Global_Scope, "string", ARGON_STRING_TYPE);
add_to_scope(Global_Scope, "type", ARGON_TYPE_TYPE); add_to_scope(Global_Scope, "type", ARGON_TYPE_TYPE);
add_to_scope(Global_Scope, "boolean", ARGON_BOOL_TYPE); 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);
ArgonObject *argon_term = new_object(); ArgonObject *argon_term = new_object();
add_field(argon_term, "__init__", ARGON_NULL); add_field(argon_term, "__init__", ARGON_NULL);
@@ -489,6 +624,9 @@ ArErr run_instruction(Translated *translated, RuntimeState *state,
case OP_LOAD_ACCESS_FUNCTION: case OP_LOAD_ACCESS_FUNCTION:
state->registers[0] = ACCESS_FUNCTION; state->registers[0] = ACCESS_FUNCTION;
break; break;
case OP_LOAD_ADDITION_FUNCTION:
state->registers[0] = ADDITION_FUNCTION;
break;
default: default:
return create_err(0, 0, 0, NULL, "Runtime Error", "Invalid Opcode %#x", return create_err(0, 0, 0, NULL, "Runtime Error", "Invalid Opcode %#x",
opcode); opcode);

View File

@@ -98,7 +98,7 @@ initialises a call instance struct and arguments buffer.
## OP_CALL ## OP_CALL
call a function with args call the function at the head of the call instance stack, then pops it off the stack.
## OP_SOURCE_LOCATION ## OP_SOURCE_LOCATION
@@ -125,12 +125,10 @@ loads a mpq_t number into memory
1. the register to write to. (*) 1. the register to write to. (*)
3. the size of the numerator in the constant buffer. 3. the size of the numerator in the constant buffer.
4. the offset in the constant buffer of the numerator. 4. the offset in the constant buffer of the numerator.
5. is integer. (*)
3. the size of the denominator in the constant buffer. 3. the size of the denominator in the constant buffer.
4. the offset in the constant buffer of the denominator. 4. the offset in the constant buffer of the denominator.
## OP_SWAP_REGISTERS ## OP_LOAD_ADDITION_FUNCTION
swap the contents in two registers loads the addition function into register 1
1. register a (*)
2. register b (*)

View File

@@ -13,30 +13,27 @@
size_t translate_parsed_number(Translated *translated, mpq_t *number, size_t translate_parsed_number(Translated *translated, mpq_t *number,
size_t to_register) { size_t to_register) {
mpz_t num, den; set_registers(translated, to_register + 1);
mpz_init(num); size_t start = push_instruction_byte(translated, OP_LOAD_NUMBER);
mpz_init(den); push_instruction_byte(translated, to_register);
mpz_set(num, mpq_numref(*number));
mpz_set(den, mpq_denref(*number));
size_t num_size; size_t num_size;
void *num_data = mpz_export(NULL, &num_size, 1, 1, 0, 0, num); void *num_data = mpz_export(NULL, &num_size, 1, 1, 0, 0, mpq_numref(*number));
size_t numerator_pos = arena_push(&translated->constants, num_data, num_size); size_t numerator_pos = arena_push(&translated->constants, num_data, num_size);
free(num_data); free(num_data);
mpz_clear(num); push_instruction_code(translated, num_size);
push_instruction_code(translated, numerator_pos);
bool is_int = mpz_cmp_ui(mpq_denref(*number), 1) == 0;
push_instruction_byte(translated, is_int);
if (!is_int) {
// Export denominator // Export denominator
size_t den_size; size_t den_size;
void *den_data = mpz_export(NULL, &den_size, 1, 1, 0, 0, den); void *den_data =
mpz_export(NULL, &den_size, 1, 1, 0, 0, mpq_denref(*number));
size_t denominator_pos = size_t denominator_pos =
arena_push(&translated->constants, den_data, den_size); arena_push(&translated->constants, den_data, den_size);
free(den_data); free(den_data);
mpz_clear(den);
set_registers(translated, to_register + 1);
size_t start = push_instruction_byte(translated, OP_LOAD_NUMBER);
push_instruction_byte(translated, to_register);
push_instruction_code(translated, num_size);
push_instruction_code(translated, numerator_pos);
push_instruction_code(translated, den_size); push_instruction_code(translated, den_size);
push_instruction_code(translated, denominator_pos); push_instruction_code(translated, denominator_pos);
}
return start; return start;
} }

View File

@@ -0,0 +1,29 @@
/*
* SPDX-FileCopyrightText: 2025 William Bell
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#include "operation.h"
#include <stddef.h>
size_t translate_operation(Translated *translated, ParsedOperation *operation,
ArErr *err) {
set_registers(translated, 1);
uint64_t first = push_instruction_byte(translated, OP_LOAD_ADDITION_FUNCTION);
push_instruction_byte(translated, OP_INIT_CALL);
push_instruction_code(translated, operation->to_operate_on.size);
for (size_t i = 0; i < operation->to_operate_on.size; i++) {
translate_parsed(translated, darray_get(&operation->to_operate_on, i), err);
push_instruction_byte(translated, OP_INSERT_ARG);
push_instruction_code(translated, i);
}
push_instruction_byte(translated, OP_SOURCE_LOCATION);
push_instruction_code(translated, operation->line);
push_instruction_code(translated, operation->column);
push_instruction_code(translated, operation->length);
push_instruction_byte(translated, OP_CALL);
return first;
}

View File

@@ -0,0 +1,15 @@
/*
* SPDX-FileCopyrightText: 2025 William Bell
*
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#ifndef BYTECODE_OPERATION_H
#define BYTECODE_OPERATION_H
#include "../translator.h"
#include "../../parser/operations/operations.h"
size_t translate_operation(Translated *translated, ParsedOperation *operation,
ArErr *err);
#endif

View File

@@ -6,16 +6,17 @@
#include "translator.h" #include "translator.h"
#include "../hash_data/hash_data.h" #include "../hash_data/hash_data.h"
#include "declaration/declaration.h" #include "access/access.h"
#include "call/call.h" #include "call/call.h"
#include "declaration/declaration.h"
#include "dowrap/dowrap.h" #include "dowrap/dowrap.h"
#include "function/function.h" #include "function/function.h"
#include "identifier/identifier.h" #include "identifier/identifier.h"
#include "if/if.h" #include "if/if.h"
#include "number/number.h" #include "number/number.h"
#include "string/string.h" #include "operation/operation.h"
#include "return/return.h" #include "return/return.h"
#include "access/access.h" #include "string/string.h"
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h> #include <stdio.h>
@@ -118,7 +119,8 @@ void set_registers(Translated *translator, uint8_t count) {
translator->registerCount = count; translator->registerCount = count;
} }
size_t translate_parsed(Translated *translated, ParsedValue *parsedValue, ArErr*err) { size_t translate_parsed(Translated *translated, ParsedValue *parsedValue,
ArErr *err) {
switch (parsedValue->type) { switch (parsedValue->type) {
case AST_STRING: case AST_STRING:
return translate_parsed_string(translated, return translate_parsed_string(translated,
@@ -142,13 +144,19 @@ size_t translate_parsed(Translated *translated, ParsedValue *parsedValue, ArErr*
case AST_IF: case AST_IF:
return translate_parsed_if(translated, (DArray *)parsedValue->data, err); return translate_parsed_if(translated, (DArray *)parsedValue->data, err);
case AST_DOWRAP: case AST_DOWRAP:
return translate_parsed_dowrap(translated, (DArray *)parsedValue->data, err); return translate_parsed_dowrap(translated, (DArray *)parsedValue->data,
err);
case AST_RETURN: case AST_RETURN:
return translate_parsed_return(translated, (ParsedReturn *)parsedValue->data, err); return translate_parsed_return(translated,
(ParsedReturn *)parsedValue->data, err);
case AST_CALL: case AST_CALL:
return translate_parsed_call(translated, (ParsedCall*)parsedValue->data, err); return translate_parsed_call(translated, (ParsedCall *)parsedValue->data,
err);
case AST_ACCESS: case AST_ACCESS:
return translate_access(translated, (ParsedAccess *)parsedValue->data, err); return translate_access(translated, (ParsedAccess *)parsedValue->data, err);
case AST_OPERATION:
return translate_operation(translated, (ParsedOperation *)parsedValue->data,
err);
} }
return 0; return 0;
} }

View File

@@ -31,7 +31,8 @@ typedef enum {
OP_SOURCE_LOCATION, OP_SOURCE_LOCATION,
OP_LOAD_ACCESS_FUNCTION, OP_LOAD_ACCESS_FUNCTION,
OP_LOAD_BOOL, OP_LOAD_BOOL,
OP_LOAD_NUMBER OP_LOAD_NUMBER,
OP_LOAD_ADDITION_FUNCTION
} OperationType; } OperationType;
void arena_resize(ConstantArena *arena, size_t new_size); void arena_resize(ConstantArena *arena, size_t new_size);

View File

@@ -1,2 +1,6 @@
let x = 1e10000 let f(x) = do
return x
let x = 10
term.log(x) term.log(x)