pass object into call if object is a method
This commit is contained in:
@@ -23,6 +23,8 @@ typedef enum ArgonType {
|
||||
TYPE_STRING,
|
||||
TYPE_FUNCTION,
|
||||
TYPE_NATIVE_FUNCTION,
|
||||
TYPE_METHOD,
|
||||
TYPE_NATIVE_METHOD,
|
||||
TYPE_OBJECT,
|
||||
} ArgonType;
|
||||
|
||||
|
||||
@@ -23,7 +23,6 @@ ParsedValueReturn parse_declaration(char *file, DArray *tokens, size_t *index) {
|
||||
return (ParsedValueReturn){err, NULL};
|
||||
}
|
||||
Token *token = darray_get(tokens, *index);
|
||||
|
||||
ParsedValue *parsedValue = checked_malloc(sizeof(ParsedValue));
|
||||
parsedValue->type = AST_DECLARATION;
|
||||
DArray *declarations = checked_malloc(sizeof(DArray));
|
||||
@@ -171,7 +170,7 @@ ParsedValueReturn parse_declaration(char *file, DArray *tokens, size_t *index) {
|
||||
|
||||
ParsedValueReturn from = parse_token(file, tokens, index, true);
|
||||
if (from.err.exists) {
|
||||
darray_free(¶meters, free_parameter);
|
||||
if (isFunction) darray_free(¶meters, free_parameter);
|
||||
free_parsed(parsedValue);
|
||||
free(parsedValue);
|
||||
return from;
|
||||
@@ -179,7 +178,7 @@ ParsedValueReturn parse_declaration(char *file, DArray *tokens, size_t *index) {
|
||||
free(declaration->from);
|
||||
declaration->from = from.value;
|
||||
if (!declaration->from) {
|
||||
darray_free(¶meters, free_parameter);
|
||||
if (isFunction) darray_free(¶meters, free_parameter);
|
||||
free_parsed(parsedValue);
|
||||
free(parsedValue);
|
||||
return (ParsedValueReturn){create_err(token->line, token->column,
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include <inttypes.h>
|
||||
#include <math.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -74,14 +75,21 @@ ArErr run_call(Translated *translated, RuntimeState *state) {
|
||||
uint8_t source_location_index = pop_bytecode(translated, state);
|
||||
ArgonObject *original_object = state->registers[from_register];
|
||||
ArgonObject *object = original_object;
|
||||
if (object->type != TYPE_FUNCTION && object->type != TYPE_NATIVE_FUNCTION) {
|
||||
int is_method =
|
||||
object->type == TYPE_METHOD || object->type == TYPE_NATIVE_METHOD;
|
||||
if (object->type != TYPE_FUNCTION && object->type != TYPE_NATIVE_FUNCTION && !is_method) {
|
||||
ArgonObject *call_method =
|
||||
get_field_for_class(get_field(object, "__class__", false), "__call__");
|
||||
if (call_method) {
|
||||
// Prepend the original object as first argument (self)
|
||||
object = call_method;
|
||||
is_method =
|
||||
object->type == TYPE_METHOD && object->type == TYPE_NATIVE_METHOD;
|
||||
}
|
||||
}
|
||||
if (is_method) {
|
||||
ArgonObject **new_call_args =
|
||||
malloc(sizeof(ArgonObject *) * (*state->call_args_length + 1));
|
||||
new_call_args[0] = object;
|
||||
new_call_args[0] = original_object;
|
||||
if (*state->call_args_length > 0) {
|
||||
memcpy(new_call_args + 1, *state->call_args, *state->call_args_length);
|
||||
}
|
||||
@@ -90,10 +98,25 @@ ArErr run_call(Translated *translated, RuntimeState *state) {
|
||||
}
|
||||
*state->call_args = new_call_args;
|
||||
(*state->call_args_length)++;
|
||||
object = call_method;
|
||||
}
|
||||
if (object->type == TYPE_FUNCTION || object->type == TYPE_METHOD) {
|
||||
SourceLocation *source_location =
|
||||
darray_get(&translated->source_locations, source_location_index);
|
||||
if (*state->call_args_length !=
|
||||
object->value.argon_fn.number_of_parameters) {
|
||||
ArgonObject *type_object_name = get_field_for_class(
|
||||
get_field(object, "__class__", false), "__name__");
|
||||
ArgonObject *object_name = get_field_for_class(object, "__name__");
|
||||
return create_err(
|
||||
source_location->line, source_location->column,
|
||||
source_location->length, state->path, "Type Error",
|
||||
"%.*s %.*s takes %" PRIu64 " argument(s) but %" PRIu64 " was given",
|
||||
(int)type_object_name->value.as_str.length,
|
||||
type_object_name->value.as_str.data,
|
||||
(int)object_name->value.as_str.length, object_name->value.as_str.data,
|
||||
object->value.argon_fn.number_of_parameters,
|
||||
*state->call_args_length);
|
||||
}
|
||||
if (object->type == TYPE_FUNCTION) {
|
||||
Stack *scope = create_scope(object->value.argon_fn.stack);
|
||||
for (size_t i = 0; i < *state->call_args_length; i++) {
|
||||
struct string_struct key = object->value.argon_fn.parameters[i];
|
||||
@@ -109,9 +132,13 @@ ArErr run_call(Translated *translated, RuntimeState *state) {
|
||||
{translated->registerCount, NULL, bytecode_darray,
|
||||
object->value.argon_fn.source_locations, translated->constants,
|
||||
object->value.argon_fn.path},
|
||||
{state->registers, 0, state->path,
|
||||
state->currentStackFramePointer, state->call_args,
|
||||
state->call_args_length, {}},
|
||||
{state->registers,
|
||||
0,
|
||||
state->path,
|
||||
state->currentStackFramePointer,
|
||||
state->call_args,
|
||||
state->call_args_length,
|
||||
{}},
|
||||
scope,
|
||||
*state->currentStackFramePointer,
|
||||
(*state->currentStackFramePointer)->depth + 1};
|
||||
@@ -142,15 +169,19 @@ ArErr run_call(Translated *translated, RuntimeState *state) {
|
||||
}
|
||||
};
|
||||
return no_err;
|
||||
} else if (object->type == TYPE_NATIVE_FUNCTION) {
|
||||
} else if (object->type == TYPE_NATIVE_FUNCTION || object->type == TYPE_NATIVE_METHOD) {
|
||||
ArErr err = no_err;
|
||||
state->registers[0] =
|
||||
object->value.native_fn(*state->call_args_length, *state->call_args,
|
||||
&err);
|
||||
state->registers[0] = object->value.native_fn(*state->call_args_length,
|
||||
*state->call_args, &err);
|
||||
return err;
|
||||
}
|
||||
SourceLocation *source_location =
|
||||
darray_get(&translated->source_locations, source_location_index);
|
||||
ArgonObject *type_object_name = get_field_for_class(get_field(object, "__class__", false), "__name__");
|
||||
return create_err(source_location->line, source_location->column, source_location->length, state->path, "Type Error", "'%.*s' object is not callable", (int)type_object_name->value.as_str.length, type_object_name->value.as_str.data);
|
||||
ArgonObject *type_object_name = get_field_for_class(
|
||||
get_field(original_object, "__class__", false), "__name__");
|
||||
return create_err(source_location->line, source_location->column,
|
||||
source_location->length, state->path, "Type Error",
|
||||
"'%.*s' object is not callable",
|
||||
(int)type_object_name->value.as_str.length,
|
||||
type_object_name->value.as_str.data);
|
||||
}
|
||||
@@ -201,7 +201,8 @@ ArErr run_instruction(Translated *translated, RuntimeState *state,
|
||||
*stack = (*stack)->prev;
|
||||
break;
|
||||
case OP_INIT_ARGS:;
|
||||
size_t size = pop_bytecode(translated, state) * sizeof(ArgonObject *);
|
||||
*state->call_args_length = pop_bytecode(translated, state);
|
||||
size_t size = *state->call_args_length * sizeof(ArgonObject *);
|
||||
if (*state->call_args) {
|
||||
*state->call_args = realloc(*state->call_args, size);
|
||||
} else {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# SPDX-FileCopyrightText: 2025 William Bell
|
||||
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
let f(name)=""
|
||||
f("bruh")()
|
||||
let x(hello, x, y) = "hello world"
|
||||
x(10,10,10)
|
||||
Reference in New Issue
Block a user