add not and or, while also improving performance.
This commit is contained in:
@@ -56,6 +56,7 @@ struct string_struct {
|
||||
};
|
||||
|
||||
typedef struct Stack {
|
||||
uint64_t fake_new_scopes;
|
||||
struct hashmap_GC *scope;
|
||||
struct Stack *prev;
|
||||
} Stack;
|
||||
|
||||
@@ -73,8 +73,7 @@ ArErr create_err(int64_t line, int64_t column, int length, char *path,
|
||||
err.length = length;
|
||||
|
||||
// Copy error type safely
|
||||
strncpy(err.type, type, sizeof(err.type) - 1);
|
||||
err.type[sizeof(err.type) - 1] = '\0';
|
||||
snprintf(err.type, sizeof(err.type), "%s",(char*)type);
|
||||
|
||||
// Format error message
|
||||
va_list args;
|
||||
|
||||
50
src/parser/not/not.c
Normal file
50
src/parser/not/not.c
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 William Bell
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
#include "not.h"
|
||||
#include "../../lexer/token.h"
|
||||
#include "../../memory.h"
|
||||
#include "../parser.h"
|
||||
#include <stdio.h>
|
||||
|
||||
ParsedValueReturn parse_not(char *file, DArray *tokens, size_t *index) {
|
||||
bool invert = true;
|
||||
(*index)++;
|
||||
while (tokens->size > *index) {
|
||||
Token *token = darray_get(tokens, *index);
|
||||
if (token->type != TOKEN_EXCLAMATION) {
|
||||
ParsedValueReturn value =
|
||||
parse_token_full(file, tokens, index, true, false);
|
||||
if (value.err.exists) {
|
||||
return value;
|
||||
} else if (!value.value) {
|
||||
return (ParsedValueReturn){create_err(token->line, token->column,
|
||||
token->length, file,
|
||||
"Syntax Error", "expected value"),
|
||||
NULL};
|
||||
}
|
||||
|
||||
ParsedValue *parsedValue = checked_malloc(sizeof(ParsedValue));
|
||||
ParsedToBool *parsedToBool = checked_malloc(sizeof(ParsedToBool));
|
||||
parsedToBool->value = value.value;
|
||||
parsedToBool->invert = invert;
|
||||
parsedValue->data = parsedToBool;
|
||||
parsedValue->type = AST_TO_BOOL;
|
||||
return (ParsedValueReturn){no_err, parsedValue};
|
||||
}
|
||||
invert = !invert;
|
||||
(*index)++;
|
||||
}
|
||||
ArErr err = error_if_finished(file, tokens, index);
|
||||
return (ParsedValueReturn){err, NULL};
|
||||
}
|
||||
|
||||
void free_not(void *ptr) {
|
||||
ParsedValue *parsedValue = ptr;
|
||||
ParsedToBool *parsedToBool = parsedValue->data;
|
||||
free_parsed(parsedToBool->value);
|
||||
free(parsedToBool->value);
|
||||
free(parsedToBool);
|
||||
}
|
||||
20
src/parser/not/not.h
Normal file
20
src/parser/not/not.h
Normal file
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 William Bell
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef NOT_H
|
||||
#define NOT_H
|
||||
#include "../parser.h"
|
||||
|
||||
typedef struct {
|
||||
bool invert;
|
||||
ParsedValue*value;
|
||||
} ParsedToBool;
|
||||
|
||||
ParsedValueReturn parse_not(char *file, DArray *tokens, size_t *index);
|
||||
|
||||
void free_not(void *ptr);
|
||||
|
||||
#endif // NOT_H
|
||||
@@ -42,24 +42,22 @@ ParsedValue convert_to_operation(DArray *to_operate_on, DArray *operations) {
|
||||
operationStruct->column = operation.column;
|
||||
operationStruct->length = operation.length;
|
||||
darray_init(&operationStruct->to_operate_on, sizeof(ParsedValue));
|
||||
size_t last_position = 0;
|
||||
size_t to_operate_on_last_position = 0;
|
||||
for (size_t i = 0; i < positions.size; i++) {
|
||||
size_t *position = darray_get(&positions, i);
|
||||
DArray to_operate_on_slice = darray_slice(
|
||||
to_operate_on, to_operate_on_last_position, (*position) + 1);
|
||||
DArray operations_slice =
|
||||
darray_slice(operations, last_position, *position);
|
||||
darray_slice(operations, to_operate_on_last_position, (*position));
|
||||
ParsedValue result =
|
||||
convert_to_operation(&to_operate_on_slice, &operations_slice);
|
||||
darray_push(&operationStruct->to_operate_on, &result);
|
||||
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_slice(operations, to_operate_on_last_position, operations->size);
|
||||
ParsedValue result =
|
||||
convert_to_operation(&to_operate_on_slice, &operations_slice);
|
||||
darray_push(&operationStruct->to_operate_on, &result);
|
||||
|
||||
@@ -1,3 +1,9 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2025 William Bell
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#include "parentheses-and-anonymous-function.h"
|
||||
#include "../../memory.h"
|
||||
#include "../assignable/identifier/identifier.h"
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
#include "assignable/identifier/identifier.h"
|
||||
#include "declaration/declaration.h"
|
||||
#include "dictionary/dictionary.h"
|
||||
#include "parentheses-and-anonymous-function/parentheses-and-anonymous-function.h"
|
||||
#include "dowrap/dowrap.h"
|
||||
#include "function/function.h"
|
||||
#include "if/if.h"
|
||||
@@ -21,8 +20,10 @@
|
||||
#include "literals/literals.h"
|
||||
#include "number/number.h"
|
||||
#include "operations/operations.h"
|
||||
#include "parentheses-and-anonymous-function/parentheses-and-anonymous-function.h"
|
||||
#include "return/return.h"
|
||||
#include "string/string.h"
|
||||
#include "not/not.h"
|
||||
#include "while/while.h"
|
||||
#include <gmp.h>
|
||||
#include <stdbool.h>
|
||||
@@ -32,10 +33,10 @@
|
||||
#include <string.h>
|
||||
|
||||
const char *ValueTypeNames[] = {
|
||||
"string", "assign", "identifier", "number",
|
||||
"if statement", "access", "call", "declaration",
|
||||
"null", "boolean", "do wrap", "operations",
|
||||
"list", "dictionary", "function", "return", "while loop"};
|
||||
"string", "assign", "identifier", "number", "if statement",
|
||||
"access", "call", "declaration", "null", "boolean",
|
||||
"do wrap", "operations", "list", "dictionary", "function",
|
||||
"return", "while loop", "not"};
|
||||
|
||||
ArErr error_if_finished(char *file, DArray *tokens, size_t *index) {
|
||||
if ((*index) >= tokens->size) {
|
||||
@@ -138,6 +139,9 @@ ParsedValueReturn parse_token_full(char *file, DArray *tokens, size_t *index,
|
||||
case TOKEN_LBRACE:
|
||||
output = parse_dictionary(file, tokens, index);
|
||||
break;
|
||||
case TOKEN_EXCLAMATION:
|
||||
output = parse_not(file, tokens, index);
|
||||
break;
|
||||
default:
|
||||
return (ParsedValueReturn){create_err(token->line, token->column,
|
||||
token->length, file, "Syntax Error",
|
||||
@@ -271,5 +275,8 @@ void free_parsed(void *ptr) {
|
||||
case AST_RETURN:
|
||||
free_parsed_return(parsed);
|
||||
break;
|
||||
case AST_TO_BOOL:
|
||||
free_not(parsed);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -50,7 +50,8 @@ typedef enum {
|
||||
AST_DICTIONARY,
|
||||
AST_FUNCTION,
|
||||
AST_RETURN,
|
||||
AST_WHILE
|
||||
AST_WHILE,
|
||||
AST_TO_BOOL
|
||||
} ValueType;
|
||||
|
||||
extern const char *ValueTypeNames[];
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include <stdint.h>
|
||||
#include "arobject.h"
|
||||
|
||||
#define ERR_MSG_MAX_LEN 256
|
||||
#define ERR_MSG_MAX_LEN 64
|
||||
|
||||
typedef struct ArErr {
|
||||
bool exists;
|
||||
|
||||
@@ -21,6 +21,7 @@ void runtime_assignment(Translated *translated, RuntimeState *state,
|
||||
if (exists) {
|
||||
hashmap_insert_GC(current_stack->scope, hash, key,
|
||||
state->registers[from_register], 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
hashmap_insert_GC(stack->scope, hash, key, state->registers[from_register],
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
|
||||
#include "call.h"
|
||||
#include "../../hash_data/hash_data.h"
|
||||
#include "../objects/literals/literals.h"
|
||||
#include "../objects/string/string.h"
|
||||
#include <inttypes.h>
|
||||
#include <math.h>
|
||||
@@ -156,7 +155,7 @@ void run_call(ArgonObject *original_object, size_t argc, ArgonObject **argv,
|
||||
*state->currentStackFramePointer,
|
||||
(*state->currentStackFramePointer)->depth + 1};
|
||||
for (size_t i = 0; i < new_stackFrame.translated.registerCount; i++) {
|
||||
new_stackFrame.state.registers[i] = ARGON_NULL;
|
||||
new_stackFrame.state.registers[i] = NULL;
|
||||
}
|
||||
if (CStackFrame) {
|
||||
runtime(new_stackFrame.translated, new_stackFrame.state,
|
||||
|
||||
@@ -15,18 +15,19 @@
|
||||
#include <string.h>
|
||||
|
||||
struct hashmap_GC *createHashmap_GC() {
|
||||
size_t size = 8;
|
||||
struct hashmap_GC *t =
|
||||
(struct hashmap_GC *)ar_alloc(sizeof(struct hashmap_GC));
|
||||
t->size = size;
|
||||
t->order = 1;
|
||||
t->list = (struct node_GC **)ar_alloc(sizeof(struct node_GC *) * size);
|
||||
memset(t->list, 0, sizeof(struct node_GC *) * size);
|
||||
t->count = 0;
|
||||
return t;
|
||||
size_t size = 8;
|
||||
struct hashmap_GC *t =
|
||||
(struct hashmap_GC *)ar_alloc(sizeof(struct hashmap_GC) + sizeof(struct node_GC *) * size);
|
||||
t->size = size;
|
||||
t->order = 1;
|
||||
t->list = (struct node_GC **)((char*)t + sizeof(struct hashmap_GC));
|
||||
memset(t->list, 0, sizeof(struct node_GC *) * size);
|
||||
t->count = 0;
|
||||
return t;
|
||||
}
|
||||
|
||||
void clear_hashmap_GC(struct hashmap_GC *t) {
|
||||
if (!t->count) return;
|
||||
t->order = 1;
|
||||
t->count = 0;
|
||||
memset(t->list, 0, sizeof(struct node_GC *) * t->size);
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
#include "number.h"
|
||||
#include "../functions/functions.h"
|
||||
#include "../string/string.h"
|
||||
#include <gmp-x86_64.h>
|
||||
#include <gmp.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdio.h>
|
||||
|
||||
@@ -13,15 +13,14 @@
|
||||
|
||||
ArgonObject *ARGON_STRING_TYPE = NULL;
|
||||
|
||||
ArgonObject *new_string_object(char *data, size_t length, uint64_t prehash,
|
||||
ArgonObject *new_string_object_without_memcpy(char *data, size_t length, uint64_t prehash,
|
||||
uint64_t hash) {
|
||||
ArgonObject *object = new_object();
|
||||
add_builtin_field(object, __class__, ARGON_STRING_TYPE);
|
||||
add_builtin_field(object, field_length,
|
||||
new_number_object_from_int64(length));
|
||||
object->type = TYPE_STRING;
|
||||
object->value.as_str.data = ar_alloc_atomic(length);
|
||||
memcpy(object->value.as_str.data, data, length);
|
||||
object->value.as_str.data = data;
|
||||
object->value.as_str.prehash = prehash;
|
||||
object->value.as_str.hash_computed = hash;
|
||||
object->value.as_str.hash = hash;
|
||||
@@ -30,6 +29,13 @@ ArgonObject *new_string_object(char *data, size_t length, uint64_t prehash,
|
||||
return object;
|
||||
}
|
||||
|
||||
ArgonObject *new_string_object(char *data, size_t length, uint64_t prehash,
|
||||
uint64_t hash) {
|
||||
char*data_copy = ar_alloc_atomic(length);
|
||||
memcpy(data_copy, data, length);
|
||||
return new_string_object_without_memcpy(data_copy,length, prehash, hash);
|
||||
}
|
||||
|
||||
ArgonObject *new_string_object_null_terminated(char *data) {
|
||||
return new_string_object(data, strlen(data), 0, 0);
|
||||
}
|
||||
@@ -10,6 +10,9 @@
|
||||
|
||||
extern ArgonObject *ARGON_STRING_TYPE;
|
||||
|
||||
ArgonObject *new_string_object_without_memcpy(char *data, size_t length, uint64_t prehash,
|
||||
uint64_t hash);
|
||||
|
||||
ArgonObject *new_string_object(char *data, size_t length, uint64_t prehash, uint64_t hash);
|
||||
|
||||
ArgonObject *new_string_object_null_terminated(char*data);
|
||||
|
||||
@@ -359,12 +359,11 @@ ArgonObject *ARGON_STRING_TYPE___add__(size_t argc, ArgonObject **argv,
|
||||
return ARGON_NULL;
|
||||
}
|
||||
size_t length = argv[0]->value.as_str.length + argv[1]->value.as_str.length;
|
||||
char *concat = malloc(length);
|
||||
char *concat = ar_alloc_atomic(length);
|
||||
memcpy(concat, argv[0]->value.as_str.data, argv[0]->value.as_str.length);
|
||||
memcpy(concat + argv[0]->value.as_str.length, argv[1]->value.as_str.data,
|
||||
argv[1]->value.as_str.length);
|
||||
ArgonObject *object = new_string_object(concat, length, 0, 0);
|
||||
free(concat);
|
||||
ArgonObject *object = new_string_object_without_memcpy(concat, length, 0, 0);
|
||||
return object;
|
||||
}
|
||||
|
||||
@@ -485,6 +484,7 @@ void bootstrap_types() {
|
||||
ARGON_NULL_TYPE = new_object();
|
||||
add_builtin_field(ARGON_NULL_TYPE, __base__, BASE_CLASS);
|
||||
ARGON_NULL = new_object();
|
||||
ARGON_NULL->type = TYPE_NULL;
|
||||
add_builtin_field(ARGON_NULL, __class__, ARGON_NULL_TYPE);
|
||||
ARGON_NULL->as_bool = false;
|
||||
|
||||
@@ -681,22 +681,27 @@ RuntimeState init_runtime_state(Translated translated, char *path) {
|
||||
NULL,
|
||||
{0, 0, 0},
|
||||
{}};
|
||||
for (size_t i = 0;i<translated.registerCount;i++) {
|
||||
runtime.registers[i] = ARGON_NULL;
|
||||
for (size_t i = 0; i < translated.registerCount; i++) {
|
||||
runtime.registers[i] = NULL;
|
||||
}
|
||||
return runtime;
|
||||
}
|
||||
|
||||
Stack *create_scope(Stack *prev) {
|
||||
Stack *stack = ar_alloc(sizeof(Stack));
|
||||
stack->scope = createHashmap_GC();
|
||||
stack->prev = prev;
|
||||
return stack;
|
||||
if (!prev || prev->scope->count) {
|
||||
Stack *stack = ar_alloc(sizeof(Stack));
|
||||
stack->fake_new_scopes = 0;
|
||||
stack->scope = createHashmap_GC();
|
||||
stack->prev = prev;
|
||||
return stack;
|
||||
}
|
||||
prev->fake_new_scopes++;
|
||||
return prev;
|
||||
}
|
||||
|
||||
void runtime(Translated _translated, RuntimeState _state, Stack *stack,
|
||||
ArErr *err) {
|
||||
static void *dispatch_table[] = {
|
||||
static void *const dispatch_table[] = {
|
||||
[OP_LOAD_STRING] = &&DO_LOAD_STRING,
|
||||
[OP_DECLARE] = &&DO_DECLARE,
|
||||
[OP_LOAD_NULL] = &&DO_LOAD_NULL,
|
||||
@@ -720,7 +725,8 @@ void runtime(Translated _translated, RuntimeState _state, Stack *stack,
|
||||
[OP_SUBTRACTION] = &&DO_SUBTRACTION,
|
||||
[OP_LOAD_ACCESS_FUNCTION] = &&DO_LOAD_ACCESS_FUNCTION,
|
||||
[OP_MULTIPLICATION] = &&DO_MULTIPLICATION,
|
||||
[OP_DIVISION] = &&DO_DIVISION};
|
||||
[OP_DIVISION] = &&DO_DIVISION,
|
||||
[OP_NOT] = &&DO_NOT};
|
||||
_state.head = 0;
|
||||
|
||||
StackFrame *currentStackFrame = ar_alloc(sizeof(StackFrame));
|
||||
@@ -756,15 +762,16 @@ void runtime(Translated _translated, RuntimeState _state, Stack *stack,
|
||||
runtime_assignment(translated, state, currentStackFrame->stack);
|
||||
continue;
|
||||
DO_BOOL: {
|
||||
uint8_t to_register = pop_byte(translated, state);
|
||||
if (likely(state->registers[to_register]->type != TYPE_OBJECT)) {
|
||||
state->registers[to_register] =
|
||||
state->registers[to_register]->as_bool ? ARGON_TRUE : ARGON_FALSE;
|
||||
if (state->registers[0] == ARGON_TRUE ||
|
||||
state->registers[0] == ARGON_FALSE)
|
||||
continue;
|
||||
if (likely(state->registers[0]->type != TYPE_OBJECT)) {
|
||||
state->registers[0] =
|
||||
state->registers[0]->as_bool ? ARGON_TRUE : ARGON_FALSE;
|
||||
continue;
|
||||
}
|
||||
ArgonObject *args[] = {ARGON_BOOL_TYPE, state->registers[0]};
|
||||
state->registers[to_register] =
|
||||
ARGON_BOOL_TYPE___new__(2, args, err, state);
|
||||
state->registers[0] = ARGON_BOOL_TYPE___new__(2, args, err, state);
|
||||
continue;
|
||||
}
|
||||
DO_JUMP_IF_FALSE: {
|
||||
@@ -775,6 +782,10 @@ void runtime(Translated _translated, RuntimeState _state, Stack *stack,
|
||||
}
|
||||
continue;
|
||||
}
|
||||
DO_NOT:
|
||||
state->registers[0] =
|
||||
state->registers[0] == ARGON_FALSE ? ARGON_TRUE : ARGON_FALSE;
|
||||
continue;
|
||||
DO_JUMP:
|
||||
state->head = pop_bytecode(translated, state);
|
||||
continue;
|
||||
@@ -785,6 +796,10 @@ void runtime(Translated _translated, RuntimeState _state, Stack *stack,
|
||||
clear_hashmap_GC(currentStackFrame->stack->scope);
|
||||
continue;
|
||||
DO_POP_SCOPE:
|
||||
if (currentStackFrame->stack->fake_new_scopes) {
|
||||
currentStackFrame->stack->fake_new_scopes--;
|
||||
goto DO_EMPTY_SCOPE;
|
||||
}
|
||||
currentStackFrame->stack = currentStackFrame->stack->prev;
|
||||
continue;
|
||||
DO_INIT_CALL: {
|
||||
|
||||
16
src/shell.c
16
src/shell.c
@@ -91,7 +91,8 @@ int execute_code(FILE *stream, char *path, Stack *scope,
|
||||
|
||||
hashmap_free(__translated.constants.hashmap, NULL);
|
||||
Translated translated = {
|
||||
__translated.registerCount, __translated.registerAssignment, NULL, {}, {}, __translated.path};
|
||||
__translated.registerCount, __translated.registerAssignment, NULL, {}, {},
|
||||
__translated.path};
|
||||
translated.bytecode.data = ar_alloc(__translated.bytecode.capacity);
|
||||
memcpy(translated.bytecode.data, __translated.bytecode.data,
|
||||
__translated.bytecode.capacity);
|
||||
@@ -198,11 +199,13 @@ int shell() {
|
||||
totranslatelength = 0;
|
||||
};
|
||||
int indent = 0;
|
||||
int last_indent = 0;
|
||||
char textBefore[] = ">>> ";
|
||||
|
||||
// Dynamic array of lines
|
||||
|
||||
do {
|
||||
last_indent = indent;
|
||||
// indent string
|
||||
size_t isz = (size_t)indent * 4;
|
||||
char *indentStr = (char *)malloc(isz + 1);
|
||||
@@ -253,7 +256,7 @@ int shell() {
|
||||
strcpy(textBefore, "... ");
|
||||
free(indentStr);
|
||||
|
||||
} while (indent > 0);
|
||||
} while (indent > 0 || last_indent != 0);
|
||||
totranslate = realloc(totranslate, totranslatelength + 1);
|
||||
totranslate[totranslatelength] = '\0';
|
||||
RuntimeState runtime_state;
|
||||
@@ -263,9 +266,12 @@ int shell() {
|
||||
if (resp) {
|
||||
continue;
|
||||
}
|
||||
ArErr err = no_err;
|
||||
argon_call(output_object, 1, (ArgonObject *[]){runtime_state.registers[0]},
|
||||
&err, &runtime_state);
|
||||
if (runtime_state.registers[0]) {
|
||||
ArErr err = no_err;
|
||||
argon_call(output_object, 1,
|
||||
(ArgonObject *[]){runtime_state.registers[0]}, &err,
|
||||
&runtime_state);
|
||||
}
|
||||
totranslatelength = 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,4 +9,4 @@
|
||||
|
||||
int shell();
|
||||
|
||||
#endif // ARGON_SHELL_H
|
||||
#endif // ARGON_SHELL_H
|
||||
@@ -71,9 +71,7 @@ initilises a function to a given register.
|
||||
|
||||
## OP_BOOL
|
||||
|
||||
converts a value in a given register into true or false depending on the result from \_\_bool\_\_
|
||||
|
||||
1. the register to read and write to. (*)
|
||||
converts a value in register 0 into true or false depending on the result from \_\_bool\_\_ (using asBool if the object is a primitive)
|
||||
|
||||
## OP_JUMP_IF_FALSE
|
||||
|
||||
@@ -181,4 +179,8 @@ performs an division between register A and register B, storing the result in re
|
||||
|
||||
1. the register A (*)
|
||||
2. the register B (*)
|
||||
2. the register C (*)
|
||||
2. the register C (*)
|
||||
|
||||
## OP_NOT
|
||||
|
||||
inverts the boolean value in register 0.
|
||||
@@ -40,7 +40,6 @@ size_t translate_parsed_if(Translated *translated, DArray *parsedIf,
|
||||
return 0;
|
||||
}
|
||||
push_instruction_byte(translated, OP_BOOL);
|
||||
push_instruction_byte(translated, 0);
|
||||
push_instruction_byte(translated, OP_JUMP_IF_FALSE);
|
||||
push_instruction_byte(translated, 0);
|
||||
uint64_t last_jump_index = push_instruction_code(translated, 0);
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
size_t translate_operation(Translated *translated, ParsedOperation *operation,
|
||||
ArErr *err) {
|
||||
if (operation->operation == TOKEN_AND) {
|
||||
if (operation->operation == TOKEN_AND || operation->operation == TOKEN_OR) {
|
||||
size_t *jump_to_if_false =
|
||||
checked_malloc(operation->to_operate_on.size * sizeof(size_t));
|
||||
uint8_t registerA = translated->registerAssignment++;
|
||||
@@ -21,7 +21,7 @@ size_t translate_operation(Translated *translated, ParsedOperation *operation,
|
||||
uint64_t position = translate_parsed(
|
||||
translated, darray_get(&operation->to_operate_on, i), err);
|
||||
if (i == 0)
|
||||
position = first;
|
||||
first = position;
|
||||
if (err->exists) {
|
||||
free(jump_to_if_false);
|
||||
return first;
|
||||
@@ -31,16 +31,21 @@ size_t translate_operation(Translated *translated, ParsedOperation *operation,
|
||||
push_instruction_byte(translated, registerA);
|
||||
|
||||
push_instruction_byte(translated, OP_BOOL);
|
||||
push_instruction_byte(translated, registerA);
|
||||
if (operation->operation == TOKEN_OR) push_instruction_byte(translated, OP_NOT);
|
||||
|
||||
push_instruction_byte(translated, OP_JUMP_IF_FALSE);
|
||||
push_instruction_byte(translated, registerA);
|
||||
push_instruction_byte(translated, 0);
|
||||
jump_to_if_false[i] = push_instruction_code(translated, 0);
|
||||
}
|
||||
for (size_t i = 0; i < operation->to_operate_on.size; i++) {
|
||||
set_instruction_code(translated, jump_to_if_false[i],
|
||||
translated->bytecode.size);
|
||||
}
|
||||
push_instruction_byte(translated, OP_COPY_TO_REGISTER);
|
||||
push_instruction_byte(translated, registerA);
|
||||
push_instruction_byte(translated, 0);
|
||||
push_instruction_byte(translated, OP_LOAD_NULL);
|
||||
push_instruction_byte(translated, registerA);
|
||||
|
||||
free(jump_to_if_false);
|
||||
return first;
|
||||
|
||||
@@ -6,10 +6,11 @@
|
||||
|
||||
#include "translator.h"
|
||||
#include "../hash_data/hash_data.h"
|
||||
#include "../parser/not/not.h"
|
||||
#include "access/access.h"
|
||||
#include "assignment/assignment.h"
|
||||
#include "call/call.h"
|
||||
#include "declaration/declaration.h"
|
||||
#include "assignment/assignment.h"
|
||||
#include "dowrap/dowrap.h"
|
||||
#include "function/function.h"
|
||||
#include "identifier/identifier.h"
|
||||
@@ -148,7 +149,8 @@ size_t translate_parsed(Translated *translated, ParsedValue *parsedValue,
|
||||
case AST_IF:
|
||||
return translate_parsed_if(translated, (DArray *)parsedValue->data, err);
|
||||
case AST_WHILE:
|
||||
return translate_parsed_while(translated, (ParsedWhile *)parsedValue->data, err);
|
||||
return translate_parsed_while(translated, (ParsedWhile *)parsedValue->data,
|
||||
err);
|
||||
case AST_DOWRAP:
|
||||
return translate_parsed_dowrap(translated, (DArray *)parsedValue->data,
|
||||
err);
|
||||
@@ -165,7 +167,15 @@ size_t translate_parsed(Translated *translated, ParsedValue *parsedValue,
|
||||
err);
|
||||
case AST_ASSIGN:
|
||||
return translate_parsed_assignment(translated,
|
||||
(ParsedAssign *)parsedValue->data, err);
|
||||
(ParsedAssign *)parsedValue->data, err);
|
||||
case AST_TO_BOOL: {
|
||||
size_t first = translate_parsed(
|
||||
translated, ((ParsedToBool *)parsedValue->data)->value, err);
|
||||
push_instruction_byte(translated, OP_BOOL);
|
||||
if (((ParsedToBool *)parsedValue->data)->invert)
|
||||
push_instruction_byte(translated, OP_NOT);
|
||||
return first;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -38,7 +38,8 @@ typedef enum {
|
||||
OP_SUBTRACTION,
|
||||
OP_LOAD_ACCESS_FUNCTION,
|
||||
OP_MULTIPLICATION,
|
||||
OP_DIVISION
|
||||
OP_DIVISION,
|
||||
OP_NOT
|
||||
} OperationType;
|
||||
|
||||
void arena_resize(ConstantArena *arena, size_t new_size);
|
||||
|
||||
@@ -18,12 +18,12 @@ size_t translate_parsed_while(Translated *translated, ParsedWhile *parsedWhile,
|
||||
translated->return_jumps = &return_jumps;
|
||||
}
|
||||
size_t first = push_instruction_byte(translated, OP_NEW_SCOPE);
|
||||
size_t start_of_loop = translate_parsed(translated, parsedWhile->condition, err);
|
||||
size_t start_of_loop =
|
||||
translate_parsed(translated, parsedWhile->condition, err);
|
||||
if (err->exists) {
|
||||
return 0;
|
||||
}
|
||||
push_instruction_byte(translated, OP_BOOL);
|
||||
push_instruction_byte(translated, 0);
|
||||
push_instruction_byte(translated, OP_JUMP_IF_FALSE);
|
||||
push_instruction_byte(translated, 0);
|
||||
uint64_t jump_index = push_instruction_code(translated, 0);
|
||||
@@ -31,9 +31,8 @@ size_t translate_parsed_while(Translated *translated, ParsedWhile *parsedWhile,
|
||||
push_instruction_byte(translated, OP_EMPTY_SCOPE);
|
||||
push_instruction_byte(translated, OP_JUMP);
|
||||
push_instruction_code(translated, start_of_loop);
|
||||
|
||||
|
||||
|
||||
set_instruction_code(translated, jump_index, translated->bytecode.size);
|
||||
push_instruction_byte(translated, OP_POP_SCOPE);
|
||||
if (translated->return_jumps) {
|
||||
push_instruction_byte(translated, OP_JUMP);
|
||||
size_t skip_return = push_instruction_code(translated, 0);
|
||||
@@ -50,8 +49,5 @@ size_t translate_parsed_while(Translated *translated, ParsedWhile *parsedWhile,
|
||||
darray_free(&return_jumps, NULL);
|
||||
translated->return_jumps = old_return_jumps;
|
||||
}
|
||||
|
||||
set_instruction_code(translated, jump_index,
|
||||
translated->bytecode.size);
|
||||
return first;
|
||||
}
|
||||
Reference in New Issue
Block a user