add functions to bytecode and continuing working on runtime objects

This commit is contained in:
2025-06-25 04:59:09 +01:00
parent 4f757cd9b8
commit a275a0a0ad
25 changed files with 161 additions and 49 deletions

View File

@@ -3,6 +3,7 @@
#include "../../memory.h"
#include "../literals/literals.h"
#include "../parser.h"
#include "../function/function.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -22,7 +23,8 @@ ParsedValue *parse_declaration(char *file, DArray *tokens, size_t *index) {
darray_push(declarations, &_declaration);
ParsedSingleDeclaration *declaration =
darray_get(declarations, declarations->size - 1);
declaration->is_function = false;
bool isFunction = false;
DArray parameters;
declaration->from = parse_null();
if (token->type != TOKEN_IDENTIFIER) {
@@ -38,8 +40,8 @@ ParsedValue *parse_declaration(char *file, DArray *tokens, size_t *index) {
return parsedValue;
token = darray_get(tokens, *index);
if (token->type == TOKEN_LPAREN) {
declaration->is_function = true;
darray_init(&declaration->parameters, sizeof(char *));
isFunction = true;
darray_init(&parameters, sizeof(char *));
(*index)++;
error_if_finished(file, tokens, index);
token = darray_get(tokens, *index);
@@ -63,7 +65,7 @@ ParsedValue *parse_declaration(char *file, DArray *tokens, size_t *index) {
}
char *parameter_name =
strcpy(checked_malloc(strlen(token->value) + 1), token->value);
darray_push(&declaration->parameters, &parameter_name);
darray_push(&parameters, &parameter_name);
(*index)++;
error_if_finished(file, tokens, index);
skip_newlines_and_indents(tokens, index);
@@ -97,6 +99,9 @@ ParsedValue *parse_declaration(char *file, DArray *tokens, size_t *index) {
token->column);
exit(EXIT_FAILURE);
}
if (isFunction) {
declaration->from = create_parsed_function(declaration->name, parameters, declaration->from);
}
if ((*index) >= tokens->size)
break;
token = darray_get(tokens, *index);
@@ -127,8 +132,6 @@ void free_string(void *ptr) {
void free_single_declaration(void *ptr) {
ParsedSingleDeclaration *declaration = ptr;
free(declaration->name);
if (declaration->is_function)
darray_free(&declaration->parameters, free_string);
free_parsed(declaration->from);
free(declaration->from);
}

View File

@@ -5,8 +5,6 @@
typedef struct {
char * name;
bool is_function;
DArray parameters; // string[]
ParsedValue * from;
} ParsedSingleDeclaration;

View File

@@ -88,5 +88,5 @@ void free_parsed_dictionary(void *ptr) {
ParsedValue *parsedValue = ptr;
DArray *parsed_dictionary = parsedValue->data;
darray_free(parsed_dictionary, free_dictionary_entry);
free(parsedValue->data);
free(parsed_dictionary);
}

View File

@@ -0,0 +1,25 @@
#include "function.h"
#include "../../memory.h"
#include <stdlib.h>
#include <string.h>
ParsedValue *create_parsed_function(char *name, DArray parameters,
ParsedValue *body) {
ParsedValue *parsedValue = checked_malloc(sizeof(ParsedValue));
parsedValue->type=AST_FUNCTION;
ParsedFunction *parsedFunction = checked_malloc(sizeof(ParsedFunction));
parsedValue->data=parsedFunction;
parsedFunction->name=strcpy(checked_malloc(strlen(name) + 1), name);
parsedFunction->body = body;
parsedFunction->parameters=parameters;
return parsedValue;
}
void free_function(void *ptr) {
ParsedValue *parsedValue = ptr;
ParsedFunction *parsed = parsedValue->data;
free_parsed(parsed->body);
free(parsed->name);
darray_free(&parsed->parameters, NULL);
free(parsed);
}

View File

@@ -0,0 +1,17 @@
#ifndef FUNCTION_H
#define FUNCTION_H
#include "../../lexer/token.h" // for Token
#include "../parser.h"
typedef struct {
char * name;
DArray parameters;
ParsedValue *body;
} ParsedFunction;
ParsedValue *create_parsed_function(char *name, DArray parameters,
ParsedValue *body);
void free_function(void *ptr);
#endif // FUNCTION_H

View File

@@ -115,5 +115,5 @@ void free_parsed_if(void *ptr) {
ParsedValue *parsedValue = ptr;
DArray *parsed_if = parsedValue->data;
darray_free(parsed_if, free_conditional);
free(parsedValue->data);
free(parsed_if);
}

View File

@@ -45,5 +45,5 @@ void free_parsed_list(void *ptr) {
ParsedValue *parsedValue = ptr;
DArray *parsed_list = parsedValue->data;
darray_free(parsed_list, free_parsed);
free(parsedValue->data);
free(parsed_list);
}

View File

@@ -8,6 +8,7 @@
#include "declaration/declaration.h"
#include "dictionary/dictionary.h"
#include "dowrap/dowrap.h"
#include "function/function.h"
#include "if/if.h"
#include "list/list.h"
#include "literals/literals.h"
@@ -24,7 +25,7 @@
const char *ValueTypeNames[] = {
"string", "assign", "identifier", "number", "if statement",
"access", "call", "declaration", "null", "boolean",
"do wrap", "operations", "list", "dictionary"};
"do wrap", "operations", "list", "dictionary", "function"};
void error_if_finished(char *file, DArray *tokens, size_t *index) {
if ((*index) >= tokens->size) {
@@ -232,5 +233,7 @@ void free_parsed(void *ptr) {
case AST_DICTIONARY:
free_parsed_dictionary(parsed);
break;
case AST_FUNCTION:
free_function(parsed);
}
}

View File

@@ -39,7 +39,8 @@ typedef enum {
AST_DOWRAP,
AST_OPERATION,
AST_LIST,
AST_DICTIONARY
AST_DICTIONARY,
AST_FUNCTION
} ValueType;
extern const char* ValueTypeNames[];

View File

View File

@@ -0,0 +1,6 @@
#ifndef FUNCTION_H
#define FUNCTION_H
#include "../object.h"
#endif // FUNCTION_H

View File

@@ -3,8 +3,12 @@
#include <string.h>
#include "null.h"
ArgonObject *ARGON_NULL_TYPE = NULL;
ArgonObject *ARGON_NULL = NULL;
void init_null() {
ARGON_NULL = init_argon_object();
ARGON_NULL_TYPE = init_argon_class("NULL_TYPE");
ARGON_NULL = init_child_argon_object(ARGON_NULL_TYPE);
ARGON_NULL->type=TYPE_NULL;
}

View File

@@ -1,19 +1,30 @@
#include "object.h"
#include "../../memory.h"
#include "../runtime.h"
#include <stdbool.h>
#include <string.h>
ArgonObject *BASE_OBJECT = NULL;
ArgonObject *BASE_CLASS = NULL;
void init_base_field() {
add_field(BASE_OBJECT, "test", BASE_OBJECT);
// add_field(BASE_CLASS, "test", BASE_CLASS);
}
ArgonObject* init_argon_object() {
ArgonObject* init_child_argon_object(ArgonObject *cls) {
ArgonObject *object = init_argon_class(NULL);
object->self = object;
object->baseObject = cls;
add_field(object, "__call__", NULL);
return object;
}
ArgonObject* init_argon_class(char*name) {
ArgonObject *object = ar_alloc(sizeof(ArgonObject));
object->name = name;
object->type = TYPE_OBJECT;
object->typeObject = NULL;
object->baseObject = BASE_OBJECT;
object->self = NULL;
object->baseObject = BASE_CLASS;
object->fields = createHashmap();
memset(&object->value, 0, sizeof(object->value));
return object;

View File

@@ -4,7 +4,7 @@
#include <gmp.h>
#include <stdbool.h>
extern ArgonObject *BASE_OBJECT;
extern ArgonObject *BASE_CLASS;
struct string_struct {
char *data;
@@ -17,14 +17,14 @@ typedef enum {
TYPE_NUMBER,
TYPE_STRING,
TYPE_FUNCTION,
TYPE_NATIVE_FUNCTION,
TYPE_OBJECT, // generic user object
} ArgonType;
struct ArgonObject {
ArgonType type;
char* name;
ArgonObject *self;
ArgonObject *baseObject;
ArgonObject *typeObject;
struct hashmap *fields; // dynamic fields/methods
union {
mpq_t as_number;
@@ -36,8 +36,8 @@ struct ArgonObject {
};
typedef struct ArgonObject ArgonObject;
void init_base_field();
ArgonObject *init_argon_object();
ArgonObject* init_child_argon_object(ArgonObject *cls);
ArgonObject* init_argon_class(char*name);
void add_field(ArgonObject*target, char* name, ArgonObject *object);
#endif // OBJECT_H

View File

@@ -4,21 +4,15 @@
#include <stdio.h>
ArgonObject *ARGON_STRING_TYPE = NULL;
ArgonObject *ARGON_STRING_BASE = NULL;
void init_string_type() {
ARGON_STRING_TYPE = init_argon_object();
ARGON_STRING_BASE = init_argon_object();
ARGON_STRING_TYPE = init_argon_class("String");
}
ArgonObject *init_string_object(char*data, size_t length) {
fwrite(data, 1, length, stdout);
printf("\n");
ArgonObject * object = init_argon_object();
object->typeObject = ARGON_STRING_TYPE;
object->baseObject = ARGON_STRING_BASE;
ArgonObject * object = init_child_argon_object(ARGON_STRING_TYPE);
object->type = TYPE_STRING;
object->value.as_str.data = data;
object->value.as_str.length = length;
return object;

View File

@@ -6,5 +6,5 @@
ArgonObject *ARGON_TYPE = NULL;
void init_type() {
ARGON_TYPE = init_argon_object();
ARGON_TYPE = init_argon_class("function");
}

View File

@@ -13,7 +13,7 @@
#include <unistd.h>
void init_types() {
BASE_OBJECT = init_argon_object();
BASE_CLASS = init_argon_class("BASE_CLASS");
init_type();
init_null();
@@ -33,7 +33,7 @@ void load_const(Translated *translated, RuntimeState *state) {
size_t length = pop_bytecode(translated, state);
uint64_t offset = pop_bytecode(translated, state);
void*data = ar_alloc(length);
void*data = ar_alloc_atomic(length);
memcpy(data, arena_get(&translated->constants,offset), length);
ArgonObject *object = ARGON_NULL;
switch (type) {
@@ -44,7 +44,7 @@ void load_const(Translated *translated, RuntimeState *state) {
state->registers[to_register] = object;
}
void run_instruction(Translated *translated, RuntimeState *state) {
void run_instruction(Translated *translated, RuntimeState *state, struct Stack stack) {
OperationType opcode = pop_bytecode(translated, state);
switch (opcode) {
case OP_LOAD_NULL:
@@ -59,9 +59,10 @@ void run_instruction(Translated *translated, RuntimeState *state) {
void runtime(Translated translated) {
RuntimeState state = {
checked_malloc(translated.registerCount * sizeof(ArgonObject *)), 0};
struct Stack stack = {};
while (state.head < translated.bytecode.size)
run_instruction(&translated, &state);
run_instruction(&translated, &state,stack);
free(state.registers);
}

View File

@@ -8,9 +8,14 @@ typedef struct {
size_t head;
} RuntimeState;
typedef struct Stack {
ArgonObject *scope;
struct Stack *prev;
} Stack;
void init_types();
void run_instruction(Translated *translated, RuntimeState *state);
void run_instruction(Translated *translated, RuntimeState *state, struct Stack stack);
void runtime(Translated translated);

View File

@@ -28,3 +28,16 @@ sets a given register to null.
this operation takes 1 operand.
1. the register to set to null.
## OP_LOAD_FUNCTION
initilises a function to a given register.
1. the offset of the name of the function.
2. the length of the name of the function.
3. the number of arguments.
4. the offset of the name of the argument.
5. the length of the name of the argument.
6. instruction 4 and 5 loop for each argument.
7. the offset of the bytecode of the function.
8. the length of the bytecode of the function.

View File

@@ -9,7 +9,6 @@ size_t translate_parsed_declaration(Translated *translated,
set_registers(translated, 1);
size_t first = 0;
for (size_t i = 0; i < delcarations.size; i++) {
// TODO: add function delclaration
ParsedSingleDeclaration *singleDeclaration = darray_get(&delcarations, i);
size_t temp = translate_parsed(translated, singleDeclaration->from);
if (i == 0)

View File

@@ -4,6 +4,32 @@
#include <stdio.h>
#include <string.h>
size_t translate_parsed_function(Translated *translated,
ParsedValue *parsedValue) {
return 0;
ParsedFunction *parsedFunction) {
DArray temp_bytecode;
darray_init(&temp_bytecode, sizeof(uint64_t));
DArray main_bytecode = translated->bytecode;
translated->bytecode = temp_bytecode;
translate_parsed(translated, parsedFunction->body);
size_t function_bytecode_offset =
arena_push(&translated->constants, translated->bytecode.data,
translated->bytecode.size);
size_t function_bytecode_length = translated->bytecode.size;
translated->bytecode = main_bytecode;
darray_free(&temp_bytecode, NULL);
size_t start = push_instruction_code(translated, OP_LOAD_FUNCTION);
size_t offset = arena_push(&translated->constants, parsedFunction->name,
strlen(parsedFunction->name));
push_instruction_code(translated, offset);
push_instruction_code(translated, strlen(parsedFunction->name));
push_instruction_code(translated, parsedFunction->parameters.size);
for (size_t i = 0; i < parsedFunction->parameters.size; i++) {
char **parameter_name = darray_get(&parsedFunction->parameters, i);
offset = arena_push(&translated->constants, *parameter_name,
strlen(*parameter_name));
push_instruction_code(translated, offset);
push_instruction_code(translated, strlen(*parameter_name));
}
push_instruction_code(translated, function_bytecode_offset);
push_instruction_code(translated, function_bytecode_length);
return start;
}

View File

@@ -1,8 +1,9 @@
#ifndef BYTECODE_FUNCTION_H
#define BYTECODE_FUNCTION_H
#include "../translator.h"
#include "../../parser/function/function.h"
size_t translate_parsed_function(Translated *translated,
ParsedValue *parsedValue);
ParsedFunction *parsedFunction);
#endif

View File

@@ -1,5 +1,6 @@
#include "translator.h"
#include "declaration/declaration.h"
#include "function/function.h"
#include "number/number.h"
#include "string/string.h"
#include <stddef.h>
@@ -81,16 +82,21 @@ void set_registers(Translated *translator, size_t count) {
size_t translate_parsed(Translated *translated, ParsedValue *parsedValue) {
switch (parsedValue->type) {
case AST_STRING:
return translate_parsed_string(translated, *((ParsedString*)parsedValue->data));
return translate_parsed_string(translated,
*((ParsedString *)parsedValue->data));
case AST_DECLARATION:
return translate_parsed_declaration(translated, *((DArray*)parsedValue->data));
return translate_parsed_declaration(translated,
*((DArray *)parsedValue->data));
case AST_NUMBER:
return translate_parsed_number(translated, (char*)parsedValue->data, 0);
return translate_parsed_number(translated, (char *)parsedValue->data, 0);
case AST_NULL:
set_registers(translated, 1);
size_t output = push_instruction_code(translated, OP_LOAD_NULL);
push_instruction_code(translated, 0);
return output;
case AST_FUNCTION:
return translate_parsed_function(translated,
(ParsedFunction *)parsedValue->data);
}
return 0;
}

View File

@@ -7,7 +7,7 @@
#include <stddef.h>
#include <stdint.h>
typedef enum { OP_LOAD_CONST = 255, OP_DECLARE, OP_LOAD_NULL } OperationType;
typedef enum { OP_LOAD_CONST = 255, OP_DECLARE, OP_LOAD_NULL, OP_LOAD_FUNCTION } OperationType;
typedef enum { TYPE_OP_STRING = 255, TYPE_OP_NUMBER } types;
typedef struct {