Compare commits

..

12 Commits

44 changed files with 1168 additions and 195 deletions

View File

@@ -26,7 +26,7 @@ full-debug: $(CFILES) $(LEXER_C) $(LEXER_H)
optimised: $(CFILES) $(LEXER_C) $(LEXER_H) optimised: $(CFILES) $(LEXER_C) $(LEXER_H)
mkdir -p bin mkdir -p bin
gcc -O3 -fprofile-generate -o $(BINARY) $(CFILES) $(CFLAGS) gcc -O3 -fprofile-generate -o $(BINARY) $(CFILES) $(CFLAGS)
${BINARY} ${BINARY} test.ar
gcc -O3 -fprofile-use -o $(BINARY) $(CFILES) $(CFLAGS) gcc -O3 -fprofile-use -o $(BINARY) $(CFILES) $(CFLAGS)

126
debug_arbin.py Normal file
View File

@@ -0,0 +1,126 @@
import struct
from enum import Enum, EnumMeta, auto
class AutoEnumMeta(EnumMeta):
@classmethod
def __prepare__(metacls, clsname, bases, **kwargs):
d = super().__prepare__(clsname, bases, **kwargs)
d['_next_value'] = 254
return d
def _generate_next_value_(cls, name, start, count, last_values):
value = cls._next_value
cls._next_value += 1
return value
class OperationType(Enum, metaclass=AutoEnumMeta):
OP_LOAD_CONST = auto()
OP_DECLARE = auto()
OP_LOAD_NULL = auto()
OP_JUMP = auto()
class Types(Enum, metaclass=AutoEnumMeta):
TYPE_OP_STRING = auto()
TYPE_OP_NUMBER = auto()
def read_arbin(filename):
with open(filename, "rb") as f:
# Read and verify file identifier (4 bytes)
file_id = f.read(4)
if file_id != b"ARBI":
raise ValueError("Invalid file identifier")
# Read version number (uint64_t, little-endian)
version_number, = struct.unpack("<Q", f.read(8))
# Read regCount, constantsSize, bytecodeSize (all uint64_t, little-endian)
reg_count, = struct.unpack("<Q", f.read(8))
constants_size, = struct.unpack("<Q", f.read(8))
bytecode_size, = struct.unpack("<Q", f.read(8))
# Read constants buffer (raw bytes)
constants = f.read(constants_size)
# Read bytecode array (uint64_t, little-endian)
bytecode = []
for _ in range(bytecode_size):
instr, = struct.unpack("<Q", f.read(8))
bytecode.append(instr)
return {
"version": version_number,
"register_count": reg_count,
"constants_size": constants_size,
"bytecode_size": bytecode_size,
"constants": constants,
"bytecode": bytecode,
}
class print_opcode:
def start(registers,data, i):
print()
match data['bytecode'][i]:
case OperationType.OP_LOAD_CONST.value:
return print_opcode.OP_LOAD_CONST(registers,data, i)
case OperationType.OP_DECLARE.value:
return print_opcode.OP_DECLARE(registers,data, i)
case OperationType.OP_LOAD_NULL.value:
return print_opcode.OP_LOAD_NULL(registers,data, i)
def OP_LOAD_CONST(registers,data, i) -> int:
print("OP_LOAD_CONST ", end="")
i+=1
register = data["bytecode"][i]
print("To Register",register,"", end="")
i+=1
match data["bytecode"][i]:
case Types.TYPE_OP_STRING.value:
print("TYPE_OP_STRING ", end="")
case Types.TYPE_OP_NUMBER.value:
print("TYPE_OP_NUMBER ", end="")
i+=1
length = data["bytecode"][i]
i+=1
offset = data["bytecode"][i]
i+=1
print("Length",length,"", end="")
print("Offset",offset,"")
registers[register] = data["constants"][offset:offset+length].decode()
print("const value:", registers[register])
return i
def OP_DECLARE(registers,data, i) -> int:
print("OP_DECLARE ", end="")
i+=1
length = data["bytecode"][i]
i+=1
offset = data["bytecode"][i]
i+=1
from_register = data["bytecode"][i]
i+=1
print("Name Length",length,"", end="")
print("Name Offset",offset,"", end="")
print("From Register",from_register,"")
print("output: let", data['constants'][offset:offset+length].decode(),'=',registers[from_register])
return i
def OP_LOAD_NULL(registers,data, i) -> int:
print("OP_LOAD_NULL ", end="")
i+=1
to_register = data["bytecode"][i]
i+=1
print("To Register",to_register,"")
registers[to_register] = "null"
return i
if __name__ == "__main__":
filename = "out.arbin"
data = read_arbin(filename)
print(f"Version: {data['version']}")
print(f"Register Count: {data['register_count']}")
print(f"Constants Size: {data['constants_size']} bytes")
print(f"Bytecode Length: {data['bytecode_size']} elements")
registers = ["null"]*data['register_count']
i=0
while i<len(data["bytecode"]):
i=print_opcode.start(registers,data,i)

2
null_test.ar Normal file
View File

@@ -0,0 +1,2 @@
null
"hello\u0000world"

View File

@@ -1,83 +0,0 @@
#include "hashmap.h"
#include <stdlib.h>
#include "../memory.h"
struct table *createTable(int size)
{
struct table *t = (struct table *)checked_malloc(sizeof(struct table));
t->size = size;
t->list = (struct node **)checked_malloc(sizeof(struct node *) * size);
int i;
for (i = 0; i < size; i++)
t->list[i] = NULL;
return t;
}
int hashCode(struct table *t, int key)
{
if (key < 0)
return -(key % t->size);
return key % t->size;
}
int remove(struct table *t, int key)
{
int pos = hashCode(t, key);
struct node *list = t->list[pos];
struct node *temp = list;
struct node *prev = NULL;
while (temp)
{
if (temp->key == key)
{
if (prev)
prev->next = temp->next;
else
t->list[pos] = temp->next;
free(temp);
return 1;
}
prev = temp;
temp = temp->next;
}
return 0;
}
void insert(struct table *t, int key, void* val)
{
int pos = hashCode(t, key);
struct node *list = t->list[pos];
struct node *newNode = (struct node *)checked_malloc(sizeof(struct node));
struct node *temp = list;
while (temp)
{
if (temp->key == key)
{
temp->val = val;
return;
}
temp = temp->next;
}
newNode->key = key;
newNode->val = val;
newNode->next = list;
t->list[pos] = newNode;
}
void *lookup(struct table *t, int key)
{
int pos = hashCode(t, key);
struct node *list = t->list[pos];
struct node *temp = list;
while (temp)
{
if (temp->key == key)
{
return temp->val;
}
temp = temp->next;
}
return NULL;
}

View File

@@ -1,24 +0,0 @@
#ifndef HASHMAP_H
#define HASHMAP_H
struct node
{
int key;
void *val;
struct node *next;
};
struct table
{
int size;
struct node **list;
};
struct table *createTable(int size);
int hashCode(struct table *t, int key);
int remove(struct table *t, int key);
void insert(struct table *t, int key, void* val);
#endif // HASHMAP_H

View File

@@ -4,8 +4,10 @@
#include "memory.h" #include "memory.h"
#include "parser/parser.h" #include "parser/parser.h"
#include "translator/translator.h" #include "translator/translator.h"
#include "runtime/runtime.h"
#include <endian.h> #include <endian.h>
#include <string.h>
#include <locale.h> #include <locale.h>
#include <stdbool.h> #include <stdbool.h>
#include <stddef.h> #include <stddef.h>
@@ -13,6 +15,9 @@
#include <stdio.h> #include <stdio.h>
#include <unistd.h> #include <unistd.h>
const char FILE_IDENTIFIER[] = "ARBI";
const uint64_t version_number = 0;
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
setlocale(LC_ALL, ""); setlocale(LC_ALL, "");
if (argc <= 1) if (argc <= 1)
@@ -52,10 +57,14 @@ int main(int argc, char *argv[]) {
uint64_t constantsSize = (uint64_t)translated.constants.size; uint64_t constantsSize = (uint64_t)translated.constants.size;
uint64_t bytecodeSize = (uint64_t)translated.bytecode.size; uint64_t bytecodeSize = (uint64_t)translated.bytecode.size;
uint64_t version_number_htole64ed = htole64(version_number);
regCount = htole64(regCount);
regCount = htole64(regCount); regCount = htole64(regCount);
constantsSize = htole64(constantsSize); constantsSize = htole64(constantsSize);
bytecodeSize = htole64(bytecodeSize); bytecodeSize = htole64(bytecodeSize);
fwrite(&FILE_IDENTIFIER, sizeof(char), strlen(FILE_IDENTIFIER), file);
fwrite(&version_number_htole64ed, sizeof(uint64_t), 1, file);
fwrite(&regCount, sizeof(uint64_t), 1, file); fwrite(&regCount, sizeof(uint64_t), 1, file);
fwrite(&constantsSize, sizeof(uint64_t), 1, file); fwrite(&constantsSize, sizeof(uint64_t), 1, file);
fwrite(&bytecodeSize, sizeof(uint64_t), 1, file); fwrite(&bytecodeSize, sizeof(uint64_t), 1, file);
@@ -65,6 +74,12 @@ int main(int argc, char *argv[]) {
fclose(file); fclose(file);
generate_siphash_key();
init_types();
runtime(translated);
free_translator(&translated); free_translator(&translated);
return 0; return 0;
} }

View File

@@ -6,6 +6,9 @@
#include <string.h> #include <string.h>
#include <stdio.h> #include <stdio.h>
// runtime
#include "runtime/objects/type/type.h"
void *checked_malloc(size_t size) { void *checked_malloc(size_t size) {
void *ptr = malloc(size); void *ptr = malloc(size);
if (!ptr) { if (!ptr) {

View File

@@ -1,6 +1,7 @@
#include "access.h" #include "access.h"
#include "../../../lexer/token.h" #include "../../../lexer/token.h"
#include "../../../memory.h" #include "../../../memory.h"
#include "../../string/string.h"
#include "../../parser.h" #include "../../parser.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@@ -18,11 +19,9 @@ ParsedValue *parse_access(char *file, DArray *tokens, size_t *index,
if (first_token->type == TOKEN_DOT) { if (first_token->type == TOKEN_DOT) {
error_if_finished(file, tokens, index); error_if_finished(file, tokens, index);
Token *token = darray_get(tokens, *index); Token *token = darray_get(tokens, *index);
ParsedValue parsedString; ParsedValue *parsedString = parse_string(token, false);
parsedString.type = AST_STRING; darray_push(&parsedAccess->access, parsedString);
parsedString.data = free(parsedString);
strcpy(checked_malloc(strlen(token->value) + 1), token->value);
darray_push(&parsedAccess->access, &parsedString);
} else { } else {
while (true) { while (true) {
skip_newlines_and_indents(tokens, index); skip_newlines_and_indents(tokens, index);

View File

@@ -2,6 +2,7 @@
#include "../../lexer/token.h" #include "../../lexer/token.h"
#include "../../memory.h" #include "../../memory.h"
#include "../parser.h" #include "../parser.h"
#include "../string/string.h"
#include <stddef.h> #include <stddef.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@@ -22,9 +23,12 @@ ParsedValue *parse_dictionary(char *file, DArray *tokens, size_t *index) {
error_if_finished(file, tokens, index); error_if_finished(file, tokens, index);
size_t keyIndex = *index; size_t keyIndex = *index;
Token *keyToken = darray_get(tokens, *index); Token *keyToken = darray_get(tokens, *index);
ParsedValue *key = parse_token(file, tokens, index, true); ParsedValue *key;
if (keyToken->type == TOKEN_IDENTIFIER) { if (keyToken->type == TOKEN_IDENTIFIER) {
key->type = AST_STRING; (*index)++;
key = parse_string(keyToken, false);
} else {
key = parse_token(file, tokens, index, true);
} }
skip_newlines_and_indents(tokens, index); skip_newlines_and_indents(tokens, index);
error_if_finished(file, tokens, index); error_if_finished(file, tokens, index);

View File

@@ -3,12 +3,156 @@
#include "../parser.h" #include "../parser.h"
#include "../../memory.h" #include "../../memory.h"
#include <gmp.h> #include <gmp.h>
#include <string.h>
// #include <stdio.h>
// #include <stdlib.h>
// #include <string.h>
// #include <ctype.h>
// int parse_exponent(const char *exp_str, long *exp_val) {
// char *endptr;
// long val = strtol(exp_str, &endptr, 10);
// if (*endptr != '\0') {
// // exponent contains invalid chars or decimal point → reject
// return -1;
// }
// *exp_val = val;
// return 0;
// }
// int mpq_set_decimal_str_exp(mpq_t r, const char *str) {
// // Skip leading whitespace
// while (isspace(*str)) str++;
// // Handle sign
// int negative = 0;
// if (*str == '-') {
// negative = 1;
// str++;
// } else if (*str == '+') {
// str++;
// }
// // Copy input to a buffer for manipulation
// size_t len = strlen(str);
// char *buf = malloc(len + 1);
// if (!buf) return -1;
// strcpy(buf, str);
// // Find 'e' or 'E'
// char *e_ptr = strchr(buf, 'e');
// if (!e_ptr) e_ptr = strchr(buf, 'E');
// char *exp_str = NULL;
// if (e_ptr) {
// *e_ptr = '\0';
// exp_str = e_ptr + 1;
// }
// // Validate decimal part (digits and one dot)
// int dot_count = 0;
// for (char *p = buf; *p; p++) {
// if (*p == '.') {
// if (++dot_count > 1) { free(buf); return -1; }
// continue;
// }
// if (!isdigit((unsigned char)*p)) { free(buf); return -1; }
// }
// // Extract integer and fractional parts
// char *dot = strchr(buf, '.');
// size_t int_len = dot ? (size_t)(dot - buf) : strlen(buf);
// size_t frac_len = dot ? strlen(dot + 1) : 0;
// // Validate exponent if present
// int exp_negative = 0;
// long exp_val = 0;
// if (exp_str) {
// // Skip leading spaces in exponent (not in regex but safe)
// while (isspace(*exp_str)) exp_str++;
// if (*exp_str == '-') {
// exp_negative = 1;
// exp_str++;
// } else if (*exp_str == '+') {
// exp_str++;
// }
// if (!isdigit((unsigned char)*exp_str)) {
// free(buf);
// return -1;
// }
// char *endptr;
// exp_val = strtol(exp_str, &endptr, 10);
// if (*endptr != '\0') {
// free(buf);
// return -1;
// }
// if (exp_negative) exp_val = -exp_val;
// }
// // Build numerator string (integer part + fractional part)
// size_t num_len = int_len + frac_len;
// if (num_len == 0) { free(buf); return -1; }
// char *num_str = malloc(num_len + 1);
// if (!num_str) { free(buf); return -1; }
// if (int_len > 0) memcpy(num_str, buf, int_len);
// if (frac_len > 0) memcpy(num_str + int_len, dot + 1, frac_len);
// num_str[num_len] = '\0';
// // Calculate denominator exponent considering exponent part
// long denom_exp = frac_len - exp_val;
// mpz_t numerator, denominator;
// mpz_init(numerator);
// mpz_init(denominator);
// if (mpz_set_str(numerator, num_str, 10) != 0) {
// free(num_str);
// free(buf);
// mpz_clear(numerator);
// mpz_clear(denominator);
// return -1;
// }
// free(num_str);
// free(buf);
// if (denom_exp >= 0) {
// mpz_ui_pow_ui(denominator, 10, (unsigned long)denom_exp);
// } else {
// // denom_exp < 0 means multiply numerator by 10^(-denom_exp)
// mpz_ui_pow_ui(denominator, 10, 0);
// mpz_ui_pow_ui(numerator, 10, (unsigned long)(-denom_exp));
// }
// if (denom_exp < 0) {
// mpz_t temp;
// mpz_init(temp);
// mpz_ui_pow_ui(temp, 10, (unsigned long)(-denom_exp));
// mpz_mul(numerator, numerator, temp);
// mpz_clear(temp);
// mpz_set_ui(denominator, 1);
// }
// mpq_set_num(r, numerator);
// mpq_set_den(r, denominator);
// mpq_canonicalize(r);
// if (negative) mpq_neg(r, r);
// mpz_clear(numerator);
// mpz_clear(denominator);
// return 0;
// }
ParsedValue *parse_number(Token *token) { ParsedValue *parse_number(Token *token) {
ParsedValue *parsedValue = checked_malloc(sizeof(ParsedValue)); ParsedValue *parsedValue = checked_malloc(sizeof(ParsedValue));
mpz_t *number = checked_malloc(sizeof(mpz_t));
mpz_init_set_str(*number, token->value, 10);
parsedValue->type = AST_NUMBER; parsedValue->type = AST_NUMBER;
parsedValue->data = number; parsedValue->data = strdup(token->value);
return parsedValue; return parsedValue;
} }

View File

@@ -1,21 +1,21 @@
#include "operations.h" #include "operations.h"
#include "../parser.h"
#include "../../memory.h" #include "../../memory.h"
#include "../parser.h"
#include <stddef.h> #include <stddef.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
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 darray_get(to_operate_on, 0); return darray_get(to_operate_on, 0);
} }
TokenType operation = 0; TokenType operation = 0;
DArray positions; DArray positions;
for (size_t i = 0; i<operations->size;i++) { for (size_t i = 0; i < operations->size; i++) {
TokenType * current_operation = darray_get(operations, i); TokenType *current_operation = darray_get(operations, i);
if (operation < *current_operation) { if (operation < *current_operation) {
if (operation!=0) { if (operation != 0) {
darray_free(&positions, NULL); darray_free(&positions, NULL);
} }
operation = *current_operation; operation = *current_operation;
@@ -23,22 +23,30 @@ ParsedValue *convert_to_operation(DArray * to_operate_on, DArray * operations) {
} }
darray_push(&positions, &i); darray_push(&positions, &i);
} }
size_t last_position = operations->size-1; ParsedValue *parsedValue = checked_malloc(sizeof(ParsedValue));
darray_push(&positions, &last_position); parsedValue->type = AST_OPERATION;
ParsedValue * parsedValue = checked_malloc(sizeof(ParsedValue)); ParsedOperation *operationStruct = checked_malloc(sizeof(ParsedOperation));
parsedValue->type = AST_OPERATION;
ParsedOperation * operationStruct = checked_malloc(sizeof(ParsedOperation));
parsedValue->data = operationStruct; parsedValue->data = operationStruct;
operationStruct->operation = operation; operationStruct->operation = operation;
darray_init(&operationStruct->to_operate_on, sizeof(ParsedValue)); darray_init(&operationStruct->to_operate_on, sizeof(ParsedValue));
last_position = 0; size_t last_position = 0;
for (size_t i = 0; i<positions.size;i++) { size_t to_operate_on_last_position = 0;
for (size_t i = 0; i < positions.size; i++) {
size_t *position = darray_get(&positions, i); size_t *position = darray_get(&positions, i);
DArray to_operate_on_slice = darray_slice(to_operate_on, last_position, *position+1); DArray to_operate_on_slice = darray_slice(
DArray operations_slice = darray_slice(operations, last_position, *position); to_operate_on, to_operate_on_last_position, (*position) + 1);
darray_push(&operationStruct->to_operate_on, convert_to_operation(&to_operate_on_slice, &operations_slice)); DArray operations_slice =
last_position = *position; darray_slice(operations, last_position, *position);
darray_push(&operationStruct->to_operate_on,
convert_to_operation(&to_operate_on_slice, &operations_slice));
last_position = (*position);
to_operate_on_last_position = (*position) + 1;
} }
DArray to_operate_on_slice =
darray_slice(to_operate_on, to_operate_on_last_position, to_operate_on->size);
DArray operations_slice = darray_slice(operations, last_position, operations->size);
darray_push(&operationStruct->to_operate_on,
convert_to_operation(&to_operate_on_slice, &operations_slice));
darray_free(&positions, NULL); darray_free(&positions, NULL);
return parsedValue; return parsedValue;
} }
@@ -48,6 +56,7 @@ ParsedValue *parse_operations(char *file, DArray *tokens, size_t *index,
DArray to_operate_on; DArray to_operate_on;
darray_init(&to_operate_on, sizeof(ParsedValue)); darray_init(&to_operate_on, sizeof(ParsedValue));
darray_push(&to_operate_on, first_parsed_value); darray_push(&to_operate_on, first_parsed_value);
free(first_parsed_value);
DArray operations; DArray operations;
darray_init(&operations, sizeof(TokenType)); darray_init(&operations, sizeof(TokenType));
@@ -66,7 +75,10 @@ ParsedValue *parse_operations(char *file, DArray *tokens, size_t *index,
darray_push(&operations, &token->type); darray_push(&operations, &token->type);
(*index)++; (*index)++;
error_if_finished(file, tokens, index); error_if_finished(file, tokens, index);
darray_push(&to_operate_on, parse_token_full(file, tokens, index, true, false)); ParsedValue *parsedValue =
parse_token_full(file, tokens, index, true, false);
darray_push(&to_operate_on, parsedValue);
free(parsedValue);
} }
ParsedValue *output = convert_to_operation(&to_operate_on, &operations); ParsedValue *output = convert_to_operation(&to_operate_on, &operations);
darray_free(&to_operate_on, NULL); darray_free(&to_operate_on, NULL);

View File

@@ -82,7 +82,7 @@ ParsedValue *parse_token_full(char *file, DArray *tokens, size_t *index,
break; break;
case TOKEN_STRING: case TOKEN_STRING:
(*index)++; (*index)++;
output = parse_string(file,token); output = parse_string(token, true);
break; break;
case TOKEN_NEW_LINE: case TOKEN_NEW_LINE:
(*index)++; (*index)++;
@@ -196,9 +196,12 @@ void free_parsed(void *ptr) {
ParsedValue *parsed = ptr; ParsedValue *parsed = ptr;
switch (parsed->type) { switch (parsed->type) {
case AST_IDENTIFIER: case AST_IDENTIFIER:
case AST_STRING: case AST_NUMBER:
free(parsed->data); free(parsed->data);
break; break;
case AST_STRING:
free_parsed_string(parsed);
break;
case AST_ASSIGN: case AST_ASSIGN:
free_parse_assign(parsed); free_parse_assign(parsed);
break; break;
@@ -211,9 +214,6 @@ void free_parsed(void *ptr) {
case AST_ACCESS: case AST_ACCESS:
free_parse_access(parsed); free_parse_access(parsed);
break; break;
case AST_NUMBER:
mpz_clear(parsed->data);
break;
case AST_NULL: case AST_NULL:
case AST_BOOLEAN: case AST_BOOLEAN:
break; break;

View File

@@ -100,7 +100,7 @@ char *unquote_json_string(const char *input, size_t *out_len) {
size_t input_len = end - (input + 1); // length inside quotes size_t input_len = end - (input + 1); // length inside quotes
const char *src = input + 1; const char *src = input + 1;
// Allocate max output size = input_len, decoded string cannot be longer than input_len // Allocate max output size = input_len, decoded string cannot be longer than input_len
char *outbuf = (char *)malloc(input_len + 1); char *outbuf = (char *)checked_malloc(input_len + 1);
if (!outbuf) return NULL; if (!outbuf) return NULL;
char *dst = outbuf; char *dst = outbuf;
@@ -245,12 +245,24 @@ char *unquote(char *str, size_t *decoded_len) {
return unescaped; return unescaped;
} }
ParsedValue *parse_string(char*file,Token* token) { ParsedValue *parse_string(Token* token, bool to_unquote) {
ParsedValue *parsedValue = checked_malloc(sizeof(ParsedValue)); ParsedValue *parsedValue = checked_malloc(sizeof(ParsedValue));
parsedValue->type = AST_STRING; parsedValue->type = AST_STRING;
ParsedString *parsedString = checked_malloc(sizeof(ParsedString)); ParsedString *parsedString = checked_malloc(sizeof(ParsedString));
parsedValue->data = parsedString; parsedValue->data = parsedString;
parsedString->length = 0; if (to_unquote) {
parsedString->string = unquote(token->value, &parsedString->length); parsedString->length = 0;
parsedString->string = unquote(token->value, &parsedString->length);
} else {
parsedString->string = strdup(token->value);
parsedString->length = token->length;
}
return parsedValue; return parsedValue;
} }
void free_parsed_string(void *ptr) {
ParsedValue *parsedValue = ptr;
ParsedString *parsedString = parsedValue->data;
free(parsedString->string);
free(parsedString);
}

View File

@@ -15,6 +15,8 @@ char *swap_quotes(char *input, char quote);
char *unquote(char *str, size_t *decoded_len); char *unquote(char *str, size_t *decoded_len);
ParsedValue *parse_string(char*file,Token* token); ParsedValue *parse_string(Token* token, bool to_unquote);
void free_parsed_string(void *ptr);
#endif // STRING_UTILS_H #endif // STRING_UTILS_H

View File

@@ -0,0 +1,112 @@
#include "hashmap.h"
#include "../../../memory.h"
#include <gc/gc.h>
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
struct hashmap *createHashmap() {
size_t size = 8;
struct hashmap *t = (struct hashmap *)ar_alloc(sizeof(struct hashmap));
t->size = size;
t->order = 1;
t->list = (struct node **)ar_alloc(sizeof(struct node *) * size);
memset(t->list, 0, sizeof(struct node *) * size);
return t;
}
void resize_hashmap(struct hashmap *t) {
int old_size = t->size;
int new_size = old_size * 2;
struct node **old_list = t->list;
// Create new list
t->list = (struct node **)ar_alloc(sizeof(struct node *) * new_size);
memset(t->list, 0, sizeof(struct node *) * new_size);
t->size = new_size;
t->count = 0;
// Rehash old entries into new list
for (int i = 0; i < old_size; i++) {
struct node *temp = old_list[i];
while (temp) {
hashmap_insert(t, temp->hash, temp->key, temp->val,
temp->order); // Will increment count
temp = temp->next;
}
}
}
int hashCode(struct hashmap *t, uint64_t hash) { return hash % t->size; }
int hashmap_remove(struct hashmap *t, uint64_t hash) {
int pos = hashCode(t, hash);
struct node *list = t->list[pos];
struct node *temp = list;
struct node *prev = NULL;
while (temp) {
if (temp->hash == hash) {
if (prev)
prev->next = temp->next;
else
t->list[pos] = temp->next;
return 1;
}
prev = temp;
temp = temp->next;
}
list = NULL;
prev = NULL;
temp = NULL;
return 0;
}
void hashmap_insert(struct hashmap *t, uint64_t hash, void *key,
void *val, size_t order) {
if (!order) {
order = t->order++;
}
if ((t->count + 1) > t->size * 0.75) {
resize_hashmap(t);
}
int pos = hashCode(t, hash);
struct node *list = t->list[pos];
struct node *temp = list;
// Check if key exists → overwrite
while (temp) {
if (temp->hash == hash) {
temp->val = val;
return;
}
temp = temp->next;
}
// Insert new node
struct node *newNode = (struct node *)ar_alloc(sizeof(struct node));
newNode->hash = hash;
newNode->key = key;
newNode->val = val;
newNode->order = order;
newNode->next = list;
t->list[pos] = newNode;
t->count++;
}
void *hashmap_lookup(struct hashmap *t, uint64_t hash) {
int pos = hashCode(t, hash);
struct node *list = t->list[pos];
struct node *temp = list;
while (temp) {
if (temp->hash == hash) {
return temp->val;
}
temp = temp->next;
}
return NULL;
}

View File

@@ -0,0 +1,33 @@
#ifndef HASHMAP_H
#define HASHMAP_H
#include <stdint.h>
#include <stdlib.h>
typedef struct ArgonObject ArgonObject;
struct node {
uint64_t hash;
void *key;
void *val;
size_t order;
struct node *next;
};
struct hashmap {
size_t size;
size_t count;
size_t order;
struct node **list;
};
struct hashmap *createHashmap();
int hashCode(struct hashmap *t, uint64_t hash);
int hashmap_remove(struct hashmap *t, uint64_t hash);
void hashmap_insert(struct hashmap *t, uint64_t hash, void *key,
void *val, size_t order);
void *hashmap_lookup(struct hashmap *t, uint64_t hash);
#endif // HASHMAP_H

View File

@@ -2,7 +2,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include "../memory.h" #include "../../../memory.h"
LinkedList *create_list(size_t data_size) { LinkedList *create_list(size_t data_size) {
LinkedList *list = checked_malloc(sizeof(LinkedList)); LinkedList *list = checked_malloc(sizeof(LinkedList));

View File

@@ -0,0 +1,185 @@
/*
SipHash reference C implementation
Copyright (c) 2012-2022 Jean-Philippe Aumasson
<jeanphilippe.aumasson@gmail.com>
Copyright (c) 2012-2014 Daniel J. Bernstein <djb@cr.yp.to>
To the extent possible under law, the author(s) have dedicated all copyright
and related and neighboring rights to this software to the public domain
worldwide. This software is distributed without any warranty.
You should have received a copy of the CC0 Public Domain Dedication along
with
this software. If not, see
<http://creativecommons.org/publicdomain/zero/1.0/>.
*/
#include "siphash.h"
#include <assert.h>
#include <stddef.h>
#include <stdint.h>
/* default: SipHash-2-4 */
#ifndef cROUNDS
#define cROUNDS 2
#endif
#ifndef dROUNDS
#define dROUNDS 4
#endif
#define ROTL(x, b) (uint64_t)(((x) << (b)) | ((x) >> (64 - (b))))
#define U32TO8_LE(p, v) \
(p)[0] = (uint8_t)((v)); \
(p)[1] = (uint8_t)((v) >> 8); \
(p)[2] = (uint8_t)((v) >> 16); \
(p)[3] = (uint8_t)((v) >> 24);
#define U64TO8_LE(p, v) \
U32TO8_LE((p), (uint32_t)((v))); \
U32TO8_LE((p) + 4, (uint32_t)((v) >> 32));
#define U8TO64_LE(p) \
(((uint64_t)((p)[0])) | ((uint64_t)((p)[1]) << 8) | \
((uint64_t)((p)[2]) << 16) | ((uint64_t)((p)[3]) << 24) | \
((uint64_t)((p)[4]) << 32) | ((uint64_t)((p)[5]) << 40) | \
((uint64_t)((p)[6]) << 48) | ((uint64_t)((p)[7]) << 56))
#define SIPROUND \
do { \
v0 += v1; \
v1 = ROTL(v1, 13); \
v1 ^= v0; \
v0 = ROTL(v0, 32); \
v2 += v3; \
v3 = ROTL(v3, 16); \
v3 ^= v2; \
v0 += v3; \
v3 = ROTL(v3, 21); \
v3 ^= v0; \
v2 += v1; \
v1 = ROTL(v1, 17); \
v1 ^= v2; \
v2 = ROTL(v2, 32); \
} while (0)
#ifdef DEBUG_SIPHASH
#include <stdio.h>
#define TRACE \
do { \
printf("(%3zu) v0 %016" PRIx64 "\n", inlen, v0); \
printf("(%3zu) v1 %016" PRIx64 "\n", inlen, v1); \
printf("(%3zu) v2 %016" PRIx64 "\n", inlen, v2); \
printf("(%3zu) v3 %016" PRIx64 "\n", inlen, v3); \
} while (0)
#else
#define TRACE
#endif
/*
Computes a SipHash value
*in: pointer to input data (read-only)
inlen: input data length in bytes (any size_t value)
*k: pointer to the key data (read-only), must be 16 bytes
*out: pointer to output data (write-only), outlen bytes must be allocated
outlen: length of the output in bytes, must be 8 or 16
*/
int siphash(const void *in, const size_t inlen, const void *k, uint8_t *out,
const size_t outlen) {
const unsigned char *ni = (const unsigned char *)in;
const unsigned char *kk = (const unsigned char *)k;
assert((outlen == 8) || (outlen == 16));
uint64_t v0 = UINT64_C(0x736f6d6570736575);
uint64_t v1 = UINT64_C(0x646f72616e646f6d);
uint64_t v2 = UINT64_C(0x6c7967656e657261);
uint64_t v3 = UINT64_C(0x7465646279746573);
uint64_t k0 = U8TO64_LE(kk);
uint64_t k1 = U8TO64_LE(kk + 8);
uint64_t m;
int i;
const unsigned char *end = ni + inlen - (inlen % sizeof(uint64_t));
const int left = inlen & 7;
uint64_t b = ((uint64_t)inlen) << 56;
v3 ^= k1;
v2 ^= k0;
v1 ^= k1;
v0 ^= k0;
if (outlen == 16)
v1 ^= 0xee;
for (; ni != end; ni += 8) {
m = U8TO64_LE(ni);
v3 ^= m;
TRACE;
for (i = 0; i < cROUNDS; ++i)
SIPROUND;
v0 ^= m;
}
switch (left) {
case 7:
b |= ((uint64_t)ni[6]) << 48;
/* FALLTHRU */
case 6:
b |= ((uint64_t)ni[5]) << 40;
/* FALLTHRU */
case 5:
b |= ((uint64_t)ni[4]) << 32;
/* FALLTHRU */
case 4:
b |= ((uint64_t)ni[3]) << 24;
/* FALLTHRU */
case 3:
b |= ((uint64_t)ni[2]) << 16;
/* FALLTHRU */
case 2:
b |= ((uint64_t)ni[1]) << 8;
/* FALLTHRU */
case 1:
b |= ((uint64_t)ni[0]);
break;
case 0:
break;
}
v3 ^= b;
TRACE;
for (i = 0; i < cROUNDS; ++i)
SIPROUND;
v0 ^= b;
if (outlen == 16)
v2 ^= 0xee;
else
v2 ^= 0xff;
TRACE;
for (i = 0; i < dROUNDS; ++i)
SIPROUND;
b = v0 ^ v1 ^ v2 ^ v3;
U64TO8_LE(out, b);
if (outlen == 8)
return 0;
v1 ^= 0xdd;
TRACE;
for (i = 0; i < dROUNDS; ++i)
SIPROUND;
b = v0 ^ v1 ^ v2 ^ v3;
U64TO8_LE(out + 8, b);
return 0;
}

View File

@@ -0,0 +1,22 @@
/*
SipHash reference C implementation
Copyright (c) 2012-2021 Jean-Philippe Aumasson
<jeanphilippe.aumasson@gmail.com>
Copyright (c) 2012-2014 Daniel J. Bernstein <djb@cr.yp.to>
To the extent possible under law, the author(s) have dedicated all copyright
and related and neighboring rights to this software to the public domain
worldwide. This software is distributed without any warranty.
You should have received a copy of the CC0 Public Domain Dedication along
with
this software. If not, see
<http://creativecommons.org/publicdomain/zero/1.0/>.
*/
#include <inttypes.h>
#include <string.h>
int siphash(const void *in, const size_t inlen, const void *k, uint8_t *out,
const size_t outlen);

View File

@@ -0,0 +1,10 @@
#include "../../internals/hashmap/hashmap.h"
#include "../object.h"
#include <string.h>
#include "null.h"
ArgonObject *ARGON_NULL = NULL;
void init_null() {
ARGON_NULL = init_argon_object();
}

View File

@@ -0,0 +1,10 @@
#ifndef NULL_H
#define NULL_H
#include "../object.h"
extern ArgonObject *ARGON_NULL;
void init_null();
#endif // NULL_H

View File

@@ -0,0 +1,24 @@
#include "object.h"
#include "../../memory.h"
#include "../runtime.h"
#include <string.h>
ArgonObject *BASE_OBJECT = NULL;
void init_base_field() {
add_field(BASE_OBJECT, "test", BASE_OBJECT);
}
ArgonObject* init_argon_object() {
ArgonObject *object = ar_alloc(sizeof(ArgonObject));
object->type = TYPE_OBJECT;
object->typeObject = NULL;
object->baseObject = BASE_OBJECT;
object->fields = createHashmap();
memset(&object->value, 0, sizeof(object->value));
return object;
}
void add_field(ArgonObject*target, char* name, ArgonObject *object) {
hashmap_insert(target->fields, siphash64_bytes(name, strlen(name)),name, object, 0);
}

View File

@@ -0,0 +1,43 @@
#ifndef OBJECT_H
#define OBJECT_H
#include "../internals/hashmap/hashmap.h"
#include <gmp.h>
#include <stdbool.h>
extern ArgonObject *BASE_OBJECT;
struct string_struct {
char *data;
size_t length;
};
typedef enum {
TYPE_NULL,
TYPE_BOOL,
TYPE_NUMBER,
TYPE_STRING,
TYPE_FUNCTION,
TYPE_NATIVE_FUNCTION,
TYPE_OBJECT, // generic user object
} ArgonType;
struct ArgonObject {
ArgonType type;
ArgonObject *baseObject;
ArgonObject *typeObject;
struct hashmap *fields; // dynamic fields/methods
union {
mpq_t as_number;
bool as_bool;
struct string_struct as_str;
void *native_fn;
// others as needed
} value;
};
typedef struct ArgonObject ArgonObject;
void init_base_field();
ArgonObject *init_argon_object();
void add_field(ArgonObject*target, char* name, ArgonObject *object);
#endif // OBJECT_H

View File

@@ -0,0 +1,25 @@
#include "../object.h"
#include <stdint.h>
#include <stdio.h>
#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();
}
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;
object->value.as_str.data = data;
object->value.as_str.length = length;
return object;
}

View File

@@ -0,0 +1,11 @@
#ifndef STRING_OBJ_H
#define STRING_OBJ_H
#include "../object.h"
extern ArgonObject *ARGON_STRING_TYPE;
void init_string_type();
ArgonObject *init_string_object(char*data, size_t length);
#endif // STRING_OBJ_H

View File

@@ -0,0 +1,10 @@
#include "../../internals/hashmap/hashmap.h"
#include "../object.h"
#include <string.h>
#include "type.h"
ArgonObject *ARGON_TYPE = NULL;
void init_type() {
ARGON_TYPE = init_argon_object();
}

View File

@@ -0,0 +1,10 @@
#ifndef TYPES_H
#define TYPES_H
#include "../object.h"
extern ArgonObject *ARGON_TYPE;
void init_type();
#endif // TYPES_H

88
src/runtime/runtime.c Normal file
View File

@@ -0,0 +1,88 @@
#include "runtime.h"
#include "../translator/translator.h"
#include "internals/siphash/siphash.h"
#include "objects/null/null.h"
#include "objects/object.h"
#include "objects/string/string.h"
#include "objects/type/type.h"
#include <fcntl.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
void init_types() {
BASE_OBJECT = init_argon_object();
init_type();
init_null();
init_string_type();
init_base_field();
}
uint64_t pop_bytecode(Translated *translated, RuntimeState *state) {
uint64_t *instruction = darray_get(&translated->bytecode, state->head++);
return *instruction;
}
void load_const(Translated *translated, RuntimeState *state) {
uint64_t to_register = pop_bytecode(translated, state);
types type = pop_bytecode(translated, state);
size_t length = pop_bytecode(translated, state);
uint64_t offset = pop_bytecode(translated, state);
void*data = ar_alloc(length);
memcpy(data, arena_get(&translated->constants,offset), length);
ArgonObject *object = ARGON_NULL;
switch (type) {
case TYPE_OP_STRING:
object = init_string_object(data, length);
break;
}
state->registers[to_register] = object;
}
void run_instruction(Translated *translated, RuntimeState *state) {
OperationType opcode = pop_bytecode(translated, state);
switch (opcode) {
case OP_LOAD_NULL:
state->registers[pop_bytecode(translated, state)] = ARGON_NULL;
break;
case OP_LOAD_CONST:
load_const(translated,state);
break;
}
}
void runtime(Translated translated) {
RuntimeState state = {
checked_malloc(translated.registerCount * sizeof(ArgonObject *)), 0};
while (state.head < translated.bytecode.size)
run_instruction(&translated, &state);
free(state.registers);
}
static uint8_t siphash_key[16];
void generate_siphash_key() {
int fd = open("/dev/urandom", O_RDONLY);
if (fd < 0 || read(fd, siphash_key, 16) != 16) {
// Fallback or abort
}
close(fd);
}
uint64_t siphash64_bytes(const void *data, size_t len) {
uint8_t out[8];
if (siphash(data, len, siphash_key, out, sizeof(out)) != 0)
return 0;
uint64_t hash = 0;
for (int i = 0; i < 8; ++i)
hash |= ((uint64_t)out[i]) << (8 * i);
return hash;
}

21
src/runtime/runtime.h Normal file
View File

@@ -0,0 +1,21 @@
#ifndef RUNTIME_H
#define RUNTIME_H
#include "../translator/translator.h"
#include "internals/hashmap/hashmap.h"
typedef struct {
ArgonObject **registers;
size_t head;
} RuntimeState;
void init_types();
void run_instruction(Translated *translated, RuntimeState *state);
void runtime(Translated translated);
uint64_t siphash64_bytes(const void *data, size_t len);
void generate_siphash_key();
#endif // RUNTIME_H

View File

@@ -0,0 +1,30 @@
# Bytecode Specification
## OP_LOAD_CONST
loads and initialises a value from the constant buffer into the provided register.
this operation 4 operands.
1. the register to write to.
2. the type of data from the constant buffer.
3. the length of the data in the constant buffer.
4. the offset in the constant buffer.
## OP_DECLARE
initilises a variable on the current scope with a given value. errors if the variable is already initilises on the current scope.
this operation takes 3 operands.
1. the length of the variable name.
2. the offset in the constant buffer of the variable name.
3. the register of the given value
## OP_LOAD_NULL
sets a given register to null.
this operation takes 1 operand.
1. the register to set to null.

View File

@@ -0,0 +1,31 @@
#include "declaration.h"
#include "../../parser/declaration/declaration.h"
#include "../translator.h"
#include <stddef.h>
#include <stdio.h>
#include <string.h>
size_t translate_parsed_declaration(Translated *translated,
DArray delcarations) {
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)
first = temp;
size_t length = strlen(singleDeclaration->name);
size_t offset =
arena_push(&translated->constants, singleDeclaration->name, length);
push_instruction_code(translated, OP_DECLARE);
push_instruction_code(translated, length);
push_instruction_code(translated, offset);
push_instruction_code(translated, 0);
}
if (delcarations.size != 1) {
push_instruction_code(translated, OP_LOAD_NULL);
push_instruction_code(translated, 0);
}
return first;
}

View File

@@ -0,0 +1,8 @@
#ifndef BYTECODE_DECLARATION_H
#define BYTECODE_DECLARATION_H
#include "../translator.h"
size_t translate_parsed_declaration(Translated *translated,
DArray delcarations);
#endif

View File

@@ -0,0 +1,9 @@
#include "function.h"
#include "../translator.h"
#include <stddef.h>
#include <stdio.h>
#include <string.h>
size_t translate_parsed_function(Translated *translated,
ParsedValue *parsedValue) {
return 0;
}

View File

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

View File

@@ -0,0 +1,20 @@
#include "../translator.h"
#include "number.h"
#include <gmp.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
size_t translate_parsed_number(Translated *translated, char *number_str, size_t to_register) {
size_t length = strlen(number_str);
size_t number_pos = arena_push(&translated->constants, number_str, length);
set_registers(translated, to_register+1);
size_t start = push_instruction_code(translated, OP_LOAD_CONST);
push_instruction_code(translated, to_register);
push_instruction_code(translated, TYPE_OP_NUMBER);
push_instruction_code(translated,length);
push_instruction_code(translated, number_pos);
return start;
}

View File

@@ -0,0 +1,7 @@
#ifndef BYTECODE_NUMBER_H
#define BYTECODE_NUMBER_H
#include "../translator.h"
size_t translate_parsed_number(Translated *translated, char *number_str, size_t to_register);
#endif

View File

@@ -1,18 +1,16 @@
#include "../translator.h" #include "../translator.h"
#include "../../parser/string/string.h" #include "string.h"
#include <stddef.h> #include <stddef.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
void translate_parsed_string(Translated *translated, ParsedValue *parsedValue) { size_t translate_parsed_string(Translated *translated, ParsedString parsedString) {
ParsedString *parsedString = (ParsedString*)parsedValue->data; size_t string_pos = arena_push(&translated->constants, parsedString.string, parsedString.length);
size_t string_pos = arena_push(&translated->constants, parsedString->string, parsedString->length);
set_registers(translated, 1); set_registers(translated, 1);
push_instruction_code(translated, OP_LOAD_CONST); size_t start = push_instruction_code(translated, OP_LOAD_CONST);
push_instruction_code(translated, 0); push_instruction_code(translated, 0);
push_instruction_code(translated, OP_TYPE_STRING); push_instruction_code(translated, TYPE_OP_STRING);
push_instruction_code(translated,parsedString->length); push_instruction_code(translated,parsedString.length);
push_instruction_code(translated, string_pos); push_instruction_code(translated, string_pos);
fwrite(parsedString->string, 1, parsedString->length, stdout); return start;
putchar('\n');
} }

View File

@@ -1,7 +1,8 @@
#ifndef STRING_H #ifndef BYTECODE_STRING_H
#define STRING_H #define BYTECODE_STRING_H
#include "../translator.h" #include "../translator.h"
#include "../../parser/string/string.h"
void translate_parsed_string(Translated * translator, ParsedValue * parsedValue); size_t translate_parsed_string(Translated *translated, ParsedString parsedString);
#endif #endif

View File

@@ -1,4 +1,6 @@
#include "translator.h" #include "translator.h"
#include "declaration/declaration.h"
#include "number/number.h"
#include "string/string.h" #include "string/string.h"
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
@@ -13,30 +15,37 @@ void arena_init(ConstantArena *arena) {
} }
void arena_resize(ConstantArena *arena, size_t new_size) { void arena_resize(ConstantArena *arena, size_t new_size) {
size_t new_capacity = ((new_size / CHUNK_SIZE) + 1)*CHUNK_SIZE; size_t new_capacity = ((new_size / CHUNK_SIZE) + 1) * CHUNK_SIZE;
if (new_capacity == arena->capacity) if (new_capacity == arena->capacity)
return; return;
arena->data = realloc(arena->data, new_capacity); arena->data = realloc(arena->data, new_capacity);
if (!arena->data) { if (!arena->data) {
fprintf(stderr, "error: failed to resize arena from %zu to %zu\n", new_capacity, arena->capacity); fprintf(stderr, "error: failed to resize arena from %zu to %zu\n",
new_capacity, arena->capacity);
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
arena->capacity = new_capacity; arena->capacity = new_capacity;
} }
void arena_free(ConstantArena *arena) { void arena_free(ConstantArena *arena) {
free(arena->data); free(arena->data);
arena->capacity = 0; arena->capacity = 0;
arena->size = 0; arena->size = 0;
} }
void * arena_get(ConstantArena *arena, size_t offset) { void *arena_get(ConstantArena *arena, size_t offset) {
return arena->data + offset; return arena->data + offset;
} }
size_t arena_push(ConstantArena *arena, const void *data, size_t length) { size_t arena_push(ConstantArena *arena, const void *data, size_t length) {
arena_resize(arena, arena->size+length); if (arena->size >= length) {
for (size_t i = 0; i <= (arena->size - length); i++) {
if (memcmp(data, arena->data + i, length) == 0) {
return i;
}
}
}
arena_resize(arena, arena->size + length);
size_t offset = arena->size; size_t offset = arena->size;
memcpy(arena->data + arena->size, data, length); memcpy(arena->data + arena->size, data, length);
arena->size += length; arena->size += length;
@@ -51,32 +60,49 @@ Translated init_translator() {
return translated; return translated;
} }
size_t push_instruction_code(Translated * translator, uint64_t code) { void set_instruction_code(Translated *translator, size_t offset,
uint64_t code) {
size_t *ptr = (translator->bytecode.data + offset);
*ptr = code;
}
size_t push_instruction_code(Translated *translator, uint64_t code) {
code = htole64(code); code = htole64(code);
size_t offset = translator->bytecode.size; size_t offset = translator->bytecode.size;
darray_push(&translator->bytecode, &code); darray_push(&translator->bytecode, &code);
return offset; return offset;
} }
void set_registers(Translated * translator, size_t count) { void set_registers(Translated *translator, size_t count) {
if (count>translator->registerCount) translator->registerCount = count; if (count > translator->registerCount)
translator->registerCount = count;
} }
void translate_parsed(Translated * translator, ParsedValue * parsedValue) { size_t translate_parsed(Translated *translated, ParsedValue *parsedValue) {
switch (parsedValue->type) { switch (parsedValue->type) {
case AST_STRING: case AST_STRING:
translate_parsed_string(translator,parsedValue); return translate_parsed_string(translated, *((ParsedString*)parsedValue->data));
case AST_DECLARATION:
return translate_parsed_declaration(translated, *((DArray*)parsedValue->data));
case AST_NUMBER:
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;
}
return 0;
}
void translate(Translated *translated, DArray *ast) {
for (size_t i = 0; i < ast->size; i++) {
ParsedValue *parsedValue = darray_get(ast, i);
translate_parsed(translated, parsedValue);
} }
} }
void translate(Translated * translator, DArray *ast) { void free_translator(Translated *translated) {
for (size_t i = 0; i<ast->size; i++) {
ParsedValue * parsedValue = darray_get(ast, i);
translate_parsed(translator,parsedValue);
}
}
void free_translator(Translated * translated) {
darray_free(&translated->bytecode, NULL); darray_free(&translated->bytecode, NULL);
arena_free(&translated->constants); arena_free(&translated->constants);
} }

View File

@@ -2,14 +2,13 @@
#define TRANSLATOR_H #define TRANSLATOR_H
#include "../dynamic_array/darray.h" #include "../dynamic_array/darray.h"
#include "../memory.h"
#include "../parser/parser.h"
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include "../dynamic_array/darray.h"
#include "../parser/parser.h"
#include "../memory.h"
typedef enum { OP_LOAD_CONST=255 } OperationType; typedef enum { OP_LOAD_CONST = 255, OP_DECLARE, OP_LOAD_NULL } OperationType;
typedef enum { OP_TYPE_STRING=255 } types; typedef enum { TYPE_OP_STRING = 255, TYPE_OP_NUMBER } types;
typedef struct { typedef struct {
void *data; void *data;
@@ -23,18 +22,22 @@ typedef struct {
ConstantArena constants; ConstantArena constants;
} Translated; } Translated;
void * arena_get(ConstantArena *arena, size_t offset); void *arena_get(ConstantArena *arena, size_t offset);
size_t arena_push(ConstantArena *arena, const void *data, size_t length); size_t arena_push(ConstantArena *arena, const void *data, size_t length);
size_t push_instruction_code(Translated * translator, uint64_t code); void set_instruction_code(Translated * translator, size_t offset, uint64_t code);
void set_registers(Translated * translator, size_t count); size_t push_instruction_code(Translated *translator, uint64_t code);
void set_registers(Translated *translator, size_t count);
Translated init_translator(); Translated init_translator();
void translate(Translated * translator, DArray *ast); size_t translate_parsed(Translated * translator, ParsedValue * parsedValue);
void free_translator(Translated * translated); void translate(Translated *translator, DArray *ast);
void free_translator(Translated *translated);
#endif #endif

29
test.ar
View File

@@ -1,3 +1,15 @@
null
"h"
"e"
"ll"
"o"
" "
"wo"
"rl"
"d"
"world"
"hello world" "hello world"
"hello world" "hello world"
"hello world" "hello world"
@@ -15,10 +27,15 @@
"hello world" "hello world"
"hello\u0000world" "hello\u0000world"
"🇬🇧" "🇬🇧"
"hello\u0000world" "\u0000"
"hello"
let hello = "helllo\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nbruhhhhh"
1.24323234e2312324
let a, let a,
b = 1, b = "hello",
c, c,
d = 42, d = 42,
temp_result, temp_result,
@@ -57,9 +74,9 @@ else term.log("bruh")
mm=1/2/4/2/4354/534/534//534//3422*404203420234+3432423324&&430234230||4320423040230423^384239423043024923%4432042304920.3432423423 mm=x/2/4/2/4354/534/534//534//3422*404203420234+3432423324&&430234230||4320423040230423^384239423043024923%4432042304920.3432423423
x = [ let x = [
'hello world', 'hello world',
'wow', 'wow',
10 10
@@ -67,8 +84,8 @@ x = [
term.log(x[0:1:1]) term.log(x[0:1:1])
y = { let y = {
'hello':10, 'hello':test,
world:'nice' world:'nice'
} }

View File

@@ -1 +0,0 @@
"\u0000"