add not and or, while also improving performance.
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -64,5 +64,6 @@ build
|
|||||||
*.yy.c
|
*.yy.c
|
||||||
*.yy.h
|
*.yy.h
|
||||||
|
|
||||||
|
__isotope__
|
||||||
__arcache__
|
__arcache__
|
||||||
argon_modules
|
argon_modules
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
let factorial(x) = do
|
|
||||||
if (x-1) return x * factorial(x-1)
|
|
||||||
return 1
|
|
||||||
|
|
||||||
let i = 10000000
|
|
||||||
term.log(factorial(10000))
|
|
||||||
while (i) do
|
|
||||||
i=i-1
|
|
||||||
130
debug_arbin.py
130
debug_arbin.py
@@ -1,130 +0,0 @@
|
|||||||
# SPDX-FileCopyrightText: 2025 William Bell
|
|
||||||
#
|
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
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)
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
# SPDX-FileCopyrightText: 2025 William Bell
|
|
||||||
|
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
let __makeFile(name, type, data) = do
|
|
||||||
let File = {name: name, type: type, data: data}
|
|
||||||
let save(path) = do
|
|
||||||
let file = file.write(path)
|
|
||||||
file.buffer(data)
|
|
||||||
file.close()
|
|
||||||
File.save = save
|
|
||||||
return File
|
|
||||||
|
|
||||||
let __multipart(req, res) = do
|
|
||||||
let boundary = buffer().from(req.headers["content-type"].splitN("boundary=", 2)[1])
|
|
||||||
let newLineSplit = buffer().from("\r\n\r\n")
|
|
||||||
let parts = req.buffer.body.split(boundary)
|
|
||||||
for (i from 0 to parts.length) do
|
|
||||||
let str = parts[i].to("string")
|
|
||||||
if (str == "" || str=="--" || str=="--\r\n") continue
|
|
||||||
str = null
|
|
||||||
let headers = {}
|
|
||||||
let lines = parts[i].splitN(newLineSplit, 2)
|
|
||||||
let headerLines = lines[0].to("string").split("\r\n")
|
|
||||||
for (j from 0 to headerLines.length) do
|
|
||||||
let header = headerLines[j].splitN(": ", 2)
|
|
||||||
if (header.length != 2) continue
|
|
||||||
headers[header[0].lower()] = header[1]
|
|
||||||
if (lines.length != 2) continue
|
|
||||||
let body = lines[1]
|
|
||||||
if (i != parts.length-1) do
|
|
||||||
body = body.slice(0, body.length-4)
|
|
||||||
if ("content-disposition" in headers) do
|
|
||||||
let disposition = headers["content-disposition"].split("; ")
|
|
||||||
if (disposition[0] == "form-data") do
|
|
||||||
let name = json.parse(disposition[1].splitN("=", 2)[1])
|
|
||||||
if (disposition.length >= 3) do
|
|
||||||
let filename = json.parse(disposition[2].splitN("=", 2)[1])
|
|
||||||
req.files[name] = __makeFile(filename, headers["content-type"], body)
|
|
||||||
else do
|
|
||||||
req.formdata[name] = body.to("string")
|
|
||||||
res.next()
|
|
||||||
|
|
||||||
|
|
||||||
let formdata(req, res) = do
|
|
||||||
req.formdata = {}
|
|
||||||
req.files = {}
|
|
||||||
|
|
||||||
if (req.method != "POST") return res.next()
|
|
||||||
if ("content-type" not in req.headers) return res.next()
|
|
||||||
let loweredContentType = req.headers["content-type"].lower()
|
|
||||||
if (loweredContentType.startswith("multipart/form-data")) return __multipart(req, res)
|
|
||||||
else if (loweredContentType.startswith("application/x-www-form-urlencoded")) req.formdata = url.decodeURLQuery(req.buffer.body.to("string"))
|
|
||||||
else if (loweredContentType.startswith("application/json")) req.formdata = json.parse(req.buffer.body.to("string"))
|
|
||||||
else req.files.file = __makeFile("file", req.headers["content-type"], req.buffer.body)
|
|
||||||
res.next()
|
|
||||||
10
gentest.py
10
gentest.py
@@ -1,10 +0,0 @@
|
|||||||
# SPDX-FileCopyrightText: 2025 William Bell
|
|
||||||
#
|
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
import random
|
|
||||||
import sys
|
|
||||||
|
|
||||||
for i in range(10000000):
|
|
||||||
sys.stdout.write("\"hello world\"\n")
|
|
||||||
|
|
||||||
BIN
perf.data.old
Normal file
BIN
perf.data.old
Normal file
Binary file not shown.
@@ -56,6 +56,7 @@ struct string_struct {
|
|||||||
};
|
};
|
||||||
|
|
||||||
typedef struct Stack {
|
typedef struct Stack {
|
||||||
|
uint64_t fake_new_scopes;
|
||||||
struct hashmap_GC *scope;
|
struct hashmap_GC *scope;
|
||||||
struct Stack *prev;
|
struct Stack *prev;
|
||||||
} Stack;
|
} Stack;
|
||||||
|
|||||||
@@ -73,8 +73,7 @@ ArErr create_err(int64_t line, int64_t column, int length, char *path,
|
|||||||
err.length = length;
|
err.length = length;
|
||||||
|
|
||||||
// Copy error type safely
|
// Copy error type safely
|
||||||
strncpy(err.type, type, sizeof(err.type) - 1);
|
snprintf(err.type, sizeof(err.type), "%s",(char*)type);
|
||||||
err.type[sizeof(err.type) - 1] = '\0';
|
|
||||||
|
|
||||||
// Format error message
|
// Format error message
|
||||||
va_list args;
|
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->column = operation.column;
|
||||||
operationStruct->length = operation.length;
|
operationStruct->length = operation.length;
|
||||||
darray_init(&operationStruct->to_operate_on, sizeof(ParsedValue));
|
darray_init(&operationStruct->to_operate_on, sizeof(ParsedValue));
|
||||||
size_t last_position = 0;
|
|
||||||
size_t to_operate_on_last_position = 0;
|
size_t to_operate_on_last_position = 0;
|
||||||
for (size_t i = 0; i < positions.size; i++) {
|
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(
|
DArray to_operate_on_slice = darray_slice(
|
||||||
to_operate_on, to_operate_on_last_position, (*position) + 1);
|
to_operate_on, to_operate_on_last_position, (*position) + 1);
|
||||||
DArray operations_slice =
|
DArray operations_slice =
|
||||||
darray_slice(operations, last_position, *position);
|
darray_slice(operations, to_operate_on_last_position, (*position));
|
||||||
ParsedValue result =
|
ParsedValue result =
|
||||||
convert_to_operation(&to_operate_on_slice, &operations_slice);
|
convert_to_operation(&to_operate_on_slice, &operations_slice);
|
||||||
darray_push(&operationStruct->to_operate_on, &result);
|
darray_push(&operationStruct->to_operate_on, &result);
|
||||||
last_position = (*position);
|
|
||||||
to_operate_on_last_position = (*position) + 1;
|
to_operate_on_last_position = (*position) + 1;
|
||||||
}
|
}
|
||||||
DArray to_operate_on_slice = darray_slice(
|
DArray to_operate_on_slice = darray_slice(
|
||||||
to_operate_on, to_operate_on_last_position, to_operate_on->size);
|
to_operate_on, to_operate_on_last_position, to_operate_on->size);
|
||||||
DArray operations_slice =
|
DArray operations_slice =
|
||||||
darray_slice(operations, last_position, operations->size);
|
darray_slice(operations, to_operate_on_last_position, operations->size);
|
||||||
ParsedValue result =
|
ParsedValue result =
|
||||||
convert_to_operation(&to_operate_on_slice, &operations_slice);
|
convert_to_operation(&to_operate_on_slice, &operations_slice);
|
||||||
darray_push(&operationStruct->to_operate_on, &result);
|
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 "parentheses-and-anonymous-function.h"
|
||||||
#include "../../memory.h"
|
#include "../../memory.h"
|
||||||
#include "../assignable/identifier/identifier.h"
|
#include "../assignable/identifier/identifier.h"
|
||||||
|
|||||||
@@ -13,7 +13,6 @@
|
|||||||
#include "assignable/identifier/identifier.h"
|
#include "assignable/identifier/identifier.h"
|
||||||
#include "declaration/declaration.h"
|
#include "declaration/declaration.h"
|
||||||
#include "dictionary/dictionary.h"
|
#include "dictionary/dictionary.h"
|
||||||
#include "parentheses-and-anonymous-function/parentheses-and-anonymous-function.h"
|
|
||||||
#include "dowrap/dowrap.h"
|
#include "dowrap/dowrap.h"
|
||||||
#include "function/function.h"
|
#include "function/function.h"
|
||||||
#include "if/if.h"
|
#include "if/if.h"
|
||||||
@@ -21,8 +20,10 @@
|
|||||||
#include "literals/literals.h"
|
#include "literals/literals.h"
|
||||||
#include "number/number.h"
|
#include "number/number.h"
|
||||||
#include "operations/operations.h"
|
#include "operations/operations.h"
|
||||||
|
#include "parentheses-and-anonymous-function/parentheses-and-anonymous-function.h"
|
||||||
#include "return/return.h"
|
#include "return/return.h"
|
||||||
#include "string/string.h"
|
#include "string/string.h"
|
||||||
|
#include "not/not.h"
|
||||||
#include "while/while.h"
|
#include "while/while.h"
|
||||||
#include <gmp.h>
|
#include <gmp.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
@@ -32,10 +33,10 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
const char *ValueTypeNames[] = {
|
const char *ValueTypeNames[] = {
|
||||||
"string", "assign", "identifier", "number",
|
"string", "assign", "identifier", "number", "if statement",
|
||||||
"if statement", "access", "call", "declaration",
|
"access", "call", "declaration", "null", "boolean",
|
||||||
"null", "boolean", "do wrap", "operations",
|
"do wrap", "operations", "list", "dictionary", "function",
|
||||||
"list", "dictionary", "function", "return", "while loop"};
|
"return", "while loop", "not"};
|
||||||
|
|
||||||
ArErr error_if_finished(char *file, DArray *tokens, size_t *index) {
|
ArErr error_if_finished(char *file, DArray *tokens, size_t *index) {
|
||||||
if ((*index) >= tokens->size) {
|
if ((*index) >= tokens->size) {
|
||||||
@@ -138,6 +139,9 @@ ParsedValueReturn parse_token_full(char *file, DArray *tokens, size_t *index,
|
|||||||
case TOKEN_LBRACE:
|
case TOKEN_LBRACE:
|
||||||
output = parse_dictionary(file, tokens, index);
|
output = parse_dictionary(file, tokens, index);
|
||||||
break;
|
break;
|
||||||
|
case TOKEN_EXCLAMATION:
|
||||||
|
output = parse_not(file, tokens, index);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return (ParsedValueReturn){create_err(token->line, token->column,
|
return (ParsedValueReturn){create_err(token->line, token->column,
|
||||||
token->length, file, "Syntax Error",
|
token->length, file, "Syntax Error",
|
||||||
@@ -271,5 +275,8 @@ void free_parsed(void *ptr) {
|
|||||||
case AST_RETURN:
|
case AST_RETURN:
|
||||||
free_parsed_return(parsed);
|
free_parsed_return(parsed);
|
||||||
break;
|
break;
|
||||||
|
case AST_TO_BOOL:
|
||||||
|
free_not(parsed);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -50,7 +50,8 @@ typedef enum {
|
|||||||
AST_DICTIONARY,
|
AST_DICTIONARY,
|
||||||
AST_FUNCTION,
|
AST_FUNCTION,
|
||||||
AST_RETURN,
|
AST_RETURN,
|
||||||
AST_WHILE
|
AST_WHILE,
|
||||||
|
AST_TO_BOOL
|
||||||
} ValueType;
|
} ValueType;
|
||||||
|
|
||||||
extern const char *ValueTypeNames[];
|
extern const char *ValueTypeNames[];
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include "arobject.h"
|
#include "arobject.h"
|
||||||
|
|
||||||
#define ERR_MSG_MAX_LEN 256
|
#define ERR_MSG_MAX_LEN 64
|
||||||
|
|
||||||
typedef struct ArErr {
|
typedef struct ArErr {
|
||||||
bool exists;
|
bool exists;
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ void runtime_assignment(Translated *translated, RuntimeState *state,
|
|||||||
if (exists) {
|
if (exists) {
|
||||||
hashmap_insert_GC(current_stack->scope, hash, key,
|
hashmap_insert_GC(current_stack->scope, hash, key,
|
||||||
state->registers[from_register], 0);
|
state->registers[from_register], 0);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
hashmap_insert_GC(stack->scope, hash, key, state->registers[from_register],
|
hashmap_insert_GC(stack->scope, hash, key, state->registers[from_register],
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
|
|
||||||
#include "call.h"
|
#include "call.h"
|
||||||
#include "../../hash_data/hash_data.h"
|
#include "../../hash_data/hash_data.h"
|
||||||
#include "../objects/literals/literals.h"
|
|
||||||
#include "../objects/string/string.h"
|
#include "../objects/string/string.h"
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
@@ -156,7 +155,7 @@ void run_call(ArgonObject *original_object, size_t argc, ArgonObject **argv,
|
|||||||
*state->currentStackFramePointer,
|
*state->currentStackFramePointer,
|
||||||
(*state->currentStackFramePointer)->depth + 1};
|
(*state->currentStackFramePointer)->depth + 1};
|
||||||
for (size_t i = 0; i < new_stackFrame.translated.registerCount; i++) {
|
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) {
|
if (CStackFrame) {
|
||||||
runtime(new_stackFrame.translated, new_stackFrame.state,
|
runtime(new_stackFrame.translated, new_stackFrame.state,
|
||||||
|
|||||||
@@ -17,16 +17,17 @@
|
|||||||
struct hashmap_GC *createHashmap_GC() {
|
struct hashmap_GC *createHashmap_GC() {
|
||||||
size_t size = 8;
|
size_t size = 8;
|
||||||
struct hashmap_GC *t =
|
struct hashmap_GC *t =
|
||||||
(struct hashmap_GC *)ar_alloc(sizeof(struct hashmap_GC));
|
(struct hashmap_GC *)ar_alloc(sizeof(struct hashmap_GC) + sizeof(struct node_GC *) * size);
|
||||||
t->size = size;
|
t->size = size;
|
||||||
t->order = 1;
|
t->order = 1;
|
||||||
t->list = (struct node_GC **)ar_alloc(sizeof(struct node_GC *) * size);
|
t->list = (struct node_GC **)((char*)t + sizeof(struct hashmap_GC));
|
||||||
memset(t->list, 0, sizeof(struct node_GC *) * size);
|
memset(t->list, 0, sizeof(struct node_GC *) * size);
|
||||||
t->count = 0;
|
t->count = 0;
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear_hashmap_GC(struct hashmap_GC *t) {
|
void clear_hashmap_GC(struct hashmap_GC *t) {
|
||||||
|
if (!t->count) return;
|
||||||
t->order = 1;
|
t->order = 1;
|
||||||
t->count = 0;
|
t->count = 0;
|
||||||
memset(t->list, 0, sizeof(struct node_GC *) * t->size);
|
memset(t->list, 0, sizeof(struct node_GC *) * t->size);
|
||||||
|
|||||||
@@ -7,7 +7,6 @@
|
|||||||
#include "number.h"
|
#include "number.h"
|
||||||
#include "../functions/functions.h"
|
#include "../functions/functions.h"
|
||||||
#include "../string/string.h"
|
#include "../string/string.h"
|
||||||
#include <gmp-x86_64.h>
|
|
||||||
#include <gmp.h>
|
#include <gmp.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|||||||
@@ -13,15 +13,14 @@
|
|||||||
|
|
||||||
ArgonObject *ARGON_STRING_TYPE = NULL;
|
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) {
|
uint64_t hash) {
|
||||||
ArgonObject *object = new_object();
|
ArgonObject *object = new_object();
|
||||||
add_builtin_field(object, __class__, ARGON_STRING_TYPE);
|
add_builtin_field(object, __class__, ARGON_STRING_TYPE);
|
||||||
add_builtin_field(object, field_length,
|
add_builtin_field(object, field_length,
|
||||||
new_number_object_from_int64(length));
|
new_number_object_from_int64(length));
|
||||||
object->type = TYPE_STRING;
|
object->type = TYPE_STRING;
|
||||||
object->value.as_str.data = ar_alloc_atomic(length);
|
object->value.as_str.data = data;
|
||||||
memcpy(object->value.as_str.data, data, length);
|
|
||||||
object->value.as_str.prehash = prehash;
|
object->value.as_str.prehash = prehash;
|
||||||
object->value.as_str.hash_computed = hash;
|
object->value.as_str.hash_computed = hash;
|
||||||
object->value.as_str.hash = 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;
|
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) {
|
ArgonObject *new_string_object_null_terminated(char *data) {
|
||||||
return new_string_object(data, strlen(data), 0, 0);
|
return new_string_object(data, strlen(data), 0, 0);
|
||||||
}
|
}
|
||||||
@@ -10,6 +10,9 @@
|
|||||||
|
|
||||||
extern ArgonObject *ARGON_STRING_TYPE;
|
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(char *data, size_t length, uint64_t prehash, uint64_t hash);
|
||||||
|
|
||||||
ArgonObject *new_string_object_null_terminated(char*data);
|
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;
|
return ARGON_NULL;
|
||||||
}
|
}
|
||||||
size_t length = argv[0]->value.as_str.length + argv[1]->value.as_str.length;
|
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.data, argv[0]->value.as_str.length);
|
||||||
memcpy(concat + argv[0]->value.as_str.length, argv[1]->value.as_str.data,
|
memcpy(concat + argv[0]->value.as_str.length, argv[1]->value.as_str.data,
|
||||||
argv[1]->value.as_str.length);
|
argv[1]->value.as_str.length);
|
||||||
ArgonObject *object = new_string_object(concat, length, 0, 0);
|
ArgonObject *object = new_string_object_without_memcpy(concat, length, 0, 0);
|
||||||
free(concat);
|
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -485,6 +484,7 @@ void bootstrap_types() {
|
|||||||
ARGON_NULL_TYPE = new_object();
|
ARGON_NULL_TYPE = new_object();
|
||||||
add_builtin_field(ARGON_NULL_TYPE, __base__, BASE_CLASS);
|
add_builtin_field(ARGON_NULL_TYPE, __base__, BASE_CLASS);
|
||||||
ARGON_NULL = new_object();
|
ARGON_NULL = new_object();
|
||||||
|
ARGON_NULL->type = TYPE_NULL;
|
||||||
add_builtin_field(ARGON_NULL, __class__, ARGON_NULL_TYPE);
|
add_builtin_field(ARGON_NULL, __class__, ARGON_NULL_TYPE);
|
||||||
ARGON_NULL->as_bool = false;
|
ARGON_NULL->as_bool = false;
|
||||||
|
|
||||||
@@ -681,22 +681,27 @@ RuntimeState init_runtime_state(Translated translated, char *path) {
|
|||||||
NULL,
|
NULL,
|
||||||
{0, 0, 0},
|
{0, 0, 0},
|
||||||
{}};
|
{}};
|
||||||
for (size_t i = 0;i<translated.registerCount;i++) {
|
for (size_t i = 0; i < translated.registerCount; i++) {
|
||||||
runtime.registers[i] = ARGON_NULL;
|
runtime.registers[i] = NULL;
|
||||||
}
|
}
|
||||||
return runtime;
|
return runtime;
|
||||||
}
|
}
|
||||||
|
|
||||||
Stack *create_scope(Stack *prev) {
|
Stack *create_scope(Stack *prev) {
|
||||||
|
if (!prev || prev->scope->count) {
|
||||||
Stack *stack = ar_alloc(sizeof(Stack));
|
Stack *stack = ar_alloc(sizeof(Stack));
|
||||||
|
stack->fake_new_scopes = 0;
|
||||||
stack->scope = createHashmap_GC();
|
stack->scope = createHashmap_GC();
|
||||||
stack->prev = prev;
|
stack->prev = prev;
|
||||||
return stack;
|
return stack;
|
||||||
|
}
|
||||||
|
prev->fake_new_scopes++;
|
||||||
|
return prev;
|
||||||
}
|
}
|
||||||
|
|
||||||
void runtime(Translated _translated, RuntimeState _state, Stack *stack,
|
void runtime(Translated _translated, RuntimeState _state, Stack *stack,
|
||||||
ArErr *err) {
|
ArErr *err) {
|
||||||
static void *dispatch_table[] = {
|
static void *const dispatch_table[] = {
|
||||||
[OP_LOAD_STRING] = &&DO_LOAD_STRING,
|
[OP_LOAD_STRING] = &&DO_LOAD_STRING,
|
||||||
[OP_DECLARE] = &&DO_DECLARE,
|
[OP_DECLARE] = &&DO_DECLARE,
|
||||||
[OP_LOAD_NULL] = &&DO_LOAD_NULL,
|
[OP_LOAD_NULL] = &&DO_LOAD_NULL,
|
||||||
@@ -720,7 +725,8 @@ void runtime(Translated _translated, RuntimeState _state, Stack *stack,
|
|||||||
[OP_SUBTRACTION] = &&DO_SUBTRACTION,
|
[OP_SUBTRACTION] = &&DO_SUBTRACTION,
|
||||||
[OP_LOAD_ACCESS_FUNCTION] = &&DO_LOAD_ACCESS_FUNCTION,
|
[OP_LOAD_ACCESS_FUNCTION] = &&DO_LOAD_ACCESS_FUNCTION,
|
||||||
[OP_MULTIPLICATION] = &&DO_MULTIPLICATION,
|
[OP_MULTIPLICATION] = &&DO_MULTIPLICATION,
|
||||||
[OP_DIVISION] = &&DO_DIVISION};
|
[OP_DIVISION] = &&DO_DIVISION,
|
||||||
|
[OP_NOT] = &&DO_NOT};
|
||||||
_state.head = 0;
|
_state.head = 0;
|
||||||
|
|
||||||
StackFrame *currentStackFrame = ar_alloc(sizeof(StackFrame));
|
StackFrame *currentStackFrame = ar_alloc(sizeof(StackFrame));
|
||||||
@@ -756,15 +762,16 @@ void runtime(Translated _translated, RuntimeState _state, Stack *stack,
|
|||||||
runtime_assignment(translated, state, currentStackFrame->stack);
|
runtime_assignment(translated, state, currentStackFrame->stack);
|
||||||
continue;
|
continue;
|
||||||
DO_BOOL: {
|
DO_BOOL: {
|
||||||
uint8_t to_register = pop_byte(translated, state);
|
if (state->registers[0] == ARGON_TRUE ||
|
||||||
if (likely(state->registers[to_register]->type != TYPE_OBJECT)) {
|
state->registers[0] == ARGON_FALSE)
|
||||||
state->registers[to_register] =
|
continue;
|
||||||
state->registers[to_register]->as_bool ? ARGON_TRUE : ARGON_FALSE;
|
if (likely(state->registers[0]->type != TYPE_OBJECT)) {
|
||||||
|
state->registers[0] =
|
||||||
|
state->registers[0]->as_bool ? ARGON_TRUE : ARGON_FALSE;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
ArgonObject *args[] = {ARGON_BOOL_TYPE, state->registers[0]};
|
ArgonObject *args[] = {ARGON_BOOL_TYPE, state->registers[0]};
|
||||||
state->registers[to_register] =
|
state->registers[0] = ARGON_BOOL_TYPE___new__(2, args, err, state);
|
||||||
ARGON_BOOL_TYPE___new__(2, args, err, state);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
DO_JUMP_IF_FALSE: {
|
DO_JUMP_IF_FALSE: {
|
||||||
@@ -775,6 +782,10 @@ void runtime(Translated _translated, RuntimeState _state, Stack *stack,
|
|||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
DO_NOT:
|
||||||
|
state->registers[0] =
|
||||||
|
state->registers[0] == ARGON_FALSE ? ARGON_TRUE : ARGON_FALSE;
|
||||||
|
continue;
|
||||||
DO_JUMP:
|
DO_JUMP:
|
||||||
state->head = pop_bytecode(translated, state);
|
state->head = pop_bytecode(translated, state);
|
||||||
continue;
|
continue;
|
||||||
@@ -785,6 +796,10 @@ void runtime(Translated _translated, RuntimeState _state, Stack *stack,
|
|||||||
clear_hashmap_GC(currentStackFrame->stack->scope);
|
clear_hashmap_GC(currentStackFrame->stack->scope);
|
||||||
continue;
|
continue;
|
||||||
DO_POP_SCOPE:
|
DO_POP_SCOPE:
|
||||||
|
if (currentStackFrame->stack->fake_new_scopes) {
|
||||||
|
currentStackFrame->stack->fake_new_scopes--;
|
||||||
|
goto DO_EMPTY_SCOPE;
|
||||||
|
}
|
||||||
currentStackFrame->stack = currentStackFrame->stack->prev;
|
currentStackFrame->stack = currentStackFrame->stack->prev;
|
||||||
continue;
|
continue;
|
||||||
DO_INIT_CALL: {
|
DO_INIT_CALL: {
|
||||||
|
|||||||
14
src/shell.c
14
src/shell.c
@@ -91,7 +91,8 @@ int execute_code(FILE *stream, char *path, Stack *scope,
|
|||||||
|
|
||||||
hashmap_free(__translated.constants.hashmap, NULL);
|
hashmap_free(__translated.constants.hashmap, NULL);
|
||||||
Translated translated = {
|
Translated translated = {
|
||||||
__translated.registerCount, __translated.registerAssignment, NULL, {}, {}, __translated.path};
|
__translated.registerCount, __translated.registerAssignment, NULL, {}, {},
|
||||||
|
__translated.path};
|
||||||
translated.bytecode.data = ar_alloc(__translated.bytecode.capacity);
|
translated.bytecode.data = ar_alloc(__translated.bytecode.capacity);
|
||||||
memcpy(translated.bytecode.data, __translated.bytecode.data,
|
memcpy(translated.bytecode.data, __translated.bytecode.data,
|
||||||
__translated.bytecode.capacity);
|
__translated.bytecode.capacity);
|
||||||
@@ -198,11 +199,13 @@ int shell() {
|
|||||||
totranslatelength = 0;
|
totranslatelength = 0;
|
||||||
};
|
};
|
||||||
int indent = 0;
|
int indent = 0;
|
||||||
|
int last_indent = 0;
|
||||||
char textBefore[] = ">>> ";
|
char textBefore[] = ">>> ";
|
||||||
|
|
||||||
// Dynamic array of lines
|
// Dynamic array of lines
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
last_indent = indent;
|
||||||
// indent string
|
// indent string
|
||||||
size_t isz = (size_t)indent * 4;
|
size_t isz = (size_t)indent * 4;
|
||||||
char *indentStr = (char *)malloc(isz + 1);
|
char *indentStr = (char *)malloc(isz + 1);
|
||||||
@@ -253,7 +256,7 @@ int shell() {
|
|||||||
strcpy(textBefore, "... ");
|
strcpy(textBefore, "... ");
|
||||||
free(indentStr);
|
free(indentStr);
|
||||||
|
|
||||||
} while (indent > 0);
|
} while (indent > 0 || last_indent != 0);
|
||||||
totranslate = realloc(totranslate, totranslatelength + 1);
|
totranslate = realloc(totranslate, totranslatelength + 1);
|
||||||
totranslate[totranslatelength] = '\0';
|
totranslate[totranslatelength] = '\0';
|
||||||
RuntimeState runtime_state;
|
RuntimeState runtime_state;
|
||||||
@@ -263,9 +266,12 @@ int shell() {
|
|||||||
if (resp) {
|
if (resp) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (runtime_state.registers[0]) {
|
||||||
ArErr err = no_err;
|
ArErr err = no_err;
|
||||||
argon_call(output_object, 1, (ArgonObject *[]){runtime_state.registers[0]},
|
argon_call(output_object, 1,
|
||||||
&err, &runtime_state);
|
(ArgonObject *[]){runtime_state.registers[0]}, &err,
|
||||||
|
&runtime_state);
|
||||||
|
}
|
||||||
totranslatelength = 0;
|
totranslatelength = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -71,9 +71,7 @@ initilises a function to a given register.
|
|||||||
|
|
||||||
## OP_BOOL
|
## OP_BOOL
|
||||||
|
|
||||||
converts a value in a given register into true or false depending on the result from \_\_bool\_\_
|
converts a value in register 0 into true or false depending on the result from \_\_bool\_\_ (using asBool if the object is a primitive)
|
||||||
|
|
||||||
1. the register to read and write to. (*)
|
|
||||||
|
|
||||||
## OP_JUMP_IF_FALSE
|
## OP_JUMP_IF_FALSE
|
||||||
|
|
||||||
@@ -182,3 +180,7 @@ performs an division between register A and register B, storing the result in re
|
|||||||
1. the register A (*)
|
1. the register A (*)
|
||||||
2. the register B (*)
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
push_instruction_byte(translated, OP_BOOL);
|
push_instruction_byte(translated, OP_BOOL);
|
||||||
push_instruction_byte(translated, 0);
|
|
||||||
push_instruction_byte(translated, OP_JUMP_IF_FALSE);
|
push_instruction_byte(translated, OP_JUMP_IF_FALSE);
|
||||||
push_instruction_byte(translated, 0);
|
push_instruction_byte(translated, 0);
|
||||||
uint64_t last_jump_index = push_instruction_code(translated, 0);
|
uint64_t last_jump_index = push_instruction_code(translated, 0);
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
size_t translate_operation(Translated *translated, ParsedOperation *operation,
|
size_t translate_operation(Translated *translated, ParsedOperation *operation,
|
||||||
ArErr *err) {
|
ArErr *err) {
|
||||||
if (operation->operation == TOKEN_AND) {
|
if (operation->operation == TOKEN_AND || operation->operation == TOKEN_OR) {
|
||||||
size_t *jump_to_if_false =
|
size_t *jump_to_if_false =
|
||||||
checked_malloc(operation->to_operate_on.size * sizeof(size_t));
|
checked_malloc(operation->to_operate_on.size * sizeof(size_t));
|
||||||
uint8_t registerA = translated->registerAssignment++;
|
uint8_t registerA = translated->registerAssignment++;
|
||||||
@@ -21,7 +21,7 @@ size_t translate_operation(Translated *translated, ParsedOperation *operation,
|
|||||||
uint64_t position = translate_parsed(
|
uint64_t position = translate_parsed(
|
||||||
translated, darray_get(&operation->to_operate_on, i), err);
|
translated, darray_get(&operation->to_operate_on, i), err);
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
position = first;
|
first = position;
|
||||||
if (err->exists) {
|
if (err->exists) {
|
||||||
free(jump_to_if_false);
|
free(jump_to_if_false);
|
||||||
return first;
|
return first;
|
||||||
@@ -31,16 +31,21 @@ size_t translate_operation(Translated *translated, ParsedOperation *operation,
|
|||||||
push_instruction_byte(translated, registerA);
|
push_instruction_byte(translated, registerA);
|
||||||
|
|
||||||
push_instruction_byte(translated, OP_BOOL);
|
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, OP_JUMP_IF_FALSE);
|
||||||
push_instruction_byte(translated, registerA);
|
push_instruction_byte(translated, 0);
|
||||||
jump_to_if_false[i] = push_instruction_code(translated, 0);
|
jump_to_if_false[i] = push_instruction_code(translated, 0);
|
||||||
}
|
}
|
||||||
for (size_t i = 0; i < operation->to_operate_on.size; i++) {
|
for (size_t i = 0; i < operation->to_operate_on.size; i++) {
|
||||||
set_instruction_code(translated, jump_to_if_false[i],
|
set_instruction_code(translated, jump_to_if_false[i],
|
||||||
translated->bytecode.size);
|
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);
|
free(jump_to_if_false);
|
||||||
return first;
|
return first;
|
||||||
|
|||||||
@@ -6,10 +6,11 @@
|
|||||||
|
|
||||||
#include "translator.h"
|
#include "translator.h"
|
||||||
#include "../hash_data/hash_data.h"
|
#include "../hash_data/hash_data.h"
|
||||||
|
#include "../parser/not/not.h"
|
||||||
#include "access/access.h"
|
#include "access/access.h"
|
||||||
|
#include "assignment/assignment.h"
|
||||||
#include "call/call.h"
|
#include "call/call.h"
|
||||||
#include "declaration/declaration.h"
|
#include "declaration/declaration.h"
|
||||||
#include "assignment/assignment.h"
|
|
||||||
#include "dowrap/dowrap.h"
|
#include "dowrap/dowrap.h"
|
||||||
#include "function/function.h"
|
#include "function/function.h"
|
||||||
#include "identifier/identifier.h"
|
#include "identifier/identifier.h"
|
||||||
@@ -148,7 +149,8 @@ size_t translate_parsed(Translated *translated, ParsedValue *parsedValue,
|
|||||||
case AST_IF:
|
case AST_IF:
|
||||||
return translate_parsed_if(translated, (DArray *)parsedValue->data, err);
|
return translate_parsed_if(translated, (DArray *)parsedValue->data, err);
|
||||||
case AST_WHILE:
|
case AST_WHILE:
|
||||||
return translate_parsed_while(translated, (ParsedWhile *)parsedValue->data, err);
|
return translate_parsed_while(translated, (ParsedWhile *)parsedValue->data,
|
||||||
|
err);
|
||||||
case AST_DOWRAP:
|
case AST_DOWRAP:
|
||||||
return translate_parsed_dowrap(translated, (DArray *)parsedValue->data,
|
return translate_parsed_dowrap(translated, (DArray *)parsedValue->data,
|
||||||
err);
|
err);
|
||||||
@@ -166,6 +168,14 @@ size_t translate_parsed(Translated *translated, ParsedValue *parsedValue,
|
|||||||
case AST_ASSIGN:
|
case AST_ASSIGN:
|
||||||
return translate_parsed_assignment(translated,
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,8 @@ typedef enum {
|
|||||||
OP_SUBTRACTION,
|
OP_SUBTRACTION,
|
||||||
OP_LOAD_ACCESS_FUNCTION,
|
OP_LOAD_ACCESS_FUNCTION,
|
||||||
OP_MULTIPLICATION,
|
OP_MULTIPLICATION,
|
||||||
OP_DIVISION
|
OP_DIVISION,
|
||||||
|
OP_NOT
|
||||||
} OperationType;
|
} OperationType;
|
||||||
|
|
||||||
void arena_resize(ConstantArena *arena, size_t new_size);
|
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;
|
translated->return_jumps = &return_jumps;
|
||||||
}
|
}
|
||||||
size_t first = push_instruction_byte(translated, OP_NEW_SCOPE);
|
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) {
|
if (err->exists) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
push_instruction_byte(translated, OP_BOOL);
|
push_instruction_byte(translated, OP_BOOL);
|
||||||
push_instruction_byte(translated, 0);
|
|
||||||
push_instruction_byte(translated, OP_JUMP_IF_FALSE);
|
push_instruction_byte(translated, OP_JUMP_IF_FALSE);
|
||||||
push_instruction_byte(translated, 0);
|
push_instruction_byte(translated, 0);
|
||||||
uint64_t jump_index = push_instruction_code(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_EMPTY_SCOPE);
|
||||||
push_instruction_byte(translated, OP_JUMP);
|
push_instruction_byte(translated, OP_JUMP);
|
||||||
push_instruction_code(translated, start_of_loop);
|
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) {
|
if (translated->return_jumps) {
|
||||||
push_instruction_byte(translated, OP_JUMP);
|
push_instruction_byte(translated, OP_JUMP);
|
||||||
size_t skip_return = push_instruction_code(translated, 0);
|
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);
|
darray_free(&return_jumps, NULL);
|
||||||
translated->return_jumps = old_return_jumps;
|
translated->return_jumps = old_return_jumps;
|
||||||
}
|
}
|
||||||
|
|
||||||
set_instruction_code(translated, jump_index,
|
|
||||||
translated->bytecode.size);
|
|
||||||
return first;
|
return first;
|
||||||
}
|
}
|
||||||
94
test.ar
94
test.ar
@@ -1,94 +0,0 @@
|
|||||||
# SPDX-FileCopyrightText: 2025 William Bell
|
|
||||||
|
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
"h"
|
|
||||||
"e"
|
|
||||||
"ll"
|
|
||||||
"o"
|
|
||||||
" "
|
|
||||||
"wo"
|
|
||||||
"rl"
|
|
||||||
"d"
|
|
||||||
"world"
|
|
||||||
"hello world"
|
|
||||||
"hello world"
|
|
||||||
"hello world"
|
|
||||||
"hello world"
|
|
||||||
"hello world"
|
|
||||||
"hello world"
|
|
||||||
"hello world"
|
|
||||||
"hello world"
|
|
||||||
"hello world"
|
|
||||||
"hello world"
|
|
||||||
"hello world"
|
|
||||||
"hello world"
|
|
||||||
"hello world"
|
|
||||||
"hello world"
|
|
||||||
"hello world"
|
|
||||||
"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,
|
|
||||||
b = "hello",
|
|
||||||
c,
|
|
||||||
d = 42,
|
|
||||||
temp_result,
|
|
||||||
compute_area(radius) = 3.1415,
|
|
||||||
identity(x) = x,
|
|
||||||
f(x)=do
|
|
||||||
term.log("hello world")
|
|
||||||
do
|
|
||||||
term.log('hello world')
|
|
||||||
term.log("hello world")
|
|
||||||
,
|
|
||||||
g(y, z),
|
|
||||||
result,
|
|
||||||
z = 0,
|
|
||||||
extremely_long_variable_name_to_test_limits,
|
|
||||||
cache_value = compute_area(5),
|
|
||||||
placeholder_fn_with_no_body(arg1, arg2, arg3),
|
|
||||||
total = identity(100),
|
|
||||||
deeply_nested_args_function(arg1, arg2, arg3, arg4, arg5),
|
|
||||||
sum = a,
|
|
||||||
another,
|
|
||||||
another_function(),
|
|
||||||
just_null_here,
|
|
||||||
x
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (x) do
|
|
||||||
term.log("hello world")
|
|
||||||
term.log("hello world")
|
|
||||||
else term.log("bruh")
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
mm=x/2/4/2/4354/534/534//534//3422*404203420234+3432423324&&430234230||4320423040230423^384239423043024923%4432042304920.3432423423
|
|
||||||
|
|
||||||
let X = [
|
|
||||||
'hello world',
|
|
||||||
'wow',
|
|
||||||
10
|
|
||||||
]
|
|
||||||
|
|
||||||
term.log(x[0:1:1])
|
|
||||||
|
|
||||||
let y = {
|
|
||||||
'hello':test,
|
|
||||||
world:'nice'
|
|
||||||
}
|
|
||||||
|
|
||||||
term.log(y['hello'],y.world)
|
|
||||||
38
test.py
38
test.py
@@ -1,38 +0,0 @@
|
|||||||
# SPDX-FileCopyrightText: 2025 William Bell
|
|
||||||
#
|
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
||||||
|
|
||||||
import string
|
|
||||||
from itertools import product
|
|
||||||
import sys
|
|
||||||
|
|
||||||
def generate_names(max_width, skip_keywords=None):
|
|
||||||
if skip_keywords is None:
|
|
||||||
skip_keywords = {"if", "else", "while", "forever", "for", "break", "continue",
|
|
||||||
"return", "let", "import", "from", "do", "true", "false", "null",
|
|
||||||
"delete", "not", "try", "catch", "in", "or", "and", "elif"}
|
|
||||||
else:
|
|
||||||
skip_keywords = set(skip_keywords)
|
|
||||||
|
|
||||||
chars = string.ascii_lowercase
|
|
||||||
first = True
|
|
||||||
write = sys.stdout.write
|
|
||||||
|
|
||||||
for length in range(1, max_width + 1):
|
|
||||||
print(length, file=sys.stderr)
|
|
||||||
i = 0
|
|
||||||
for p in product(chars, repeat=length):
|
|
||||||
name = ''.join(p)
|
|
||||||
if name in skip_keywords:
|
|
||||||
continue
|
|
||||||
write('let ')
|
|
||||||
write(name)
|
|
||||||
write(' = null\n')
|
|
||||||
first = False
|
|
||||||
if i>10000000:
|
|
||||||
break
|
|
||||||
i+=1
|
|
||||||
|
|
||||||
# Example usage:
|
|
||||||
max_width = 5
|
|
||||||
generate_names(max_width)
|
|
||||||
47
testing.ar
47
testing.ar
@@ -1,47 +0,0 @@
|
|||||||
let say_hi(name) = do
|
|
||||||
let z(y) = do
|
|
||||||
return y
|
|
||||||
let u = z(
|
|
||||||
do
|
|
||||||
return name
|
|
||||||
)
|
|
||||||
|
|
||||||
return "hello "+u+", how are you?"
|
|
||||||
term.log(say_hi("william")
|
|
||||||
, say_hi)
|
|
||||||
|
|
||||||
let a = 9
|
|
||||||
let b = 10
|
|
||||||
term.log(string(a)+'+'+string(b)+'='+string(a+b))
|
|
||||||
|
|
||||||
|
|
||||||
let call(f) = do
|
|
||||||
term.log(f)
|
|
||||||
|
|
||||||
return f()
|
|
||||||
|
|
||||||
|
|
||||||
term.log(
|
|
||||||
call(
|
|
||||||
()=call(
|
|
||||||
()=do
|
|
||||||
term.log('hello testing testing')
|
|
||||||
return call(
|
|
||||||
()=call(
|
|
||||||
()=do
|
|
||||||
term.log("hello this is a test of anonymous functions. hopefully this works :)")
|
|
||||||
|
|
||||||
return say_hi("test")
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
call(()=do
|
|
||||||
term.log((
|
|
||||||
(x)=x
|
|
||||||
)(
|
|
||||||
10000675435574942378423458324823473205237523053278452368578032472390453275238558438905348905894035890348905349805345485843578934268954328902589607469328905490832678934728969834689057843267854736890256743928563256749016078596789416895657435690769013674516750941765438576867893726789543789345678576846715416789058903890549045839804538905389045890435890349580348905894035890435784785236523656237985678342523678
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
3
tests/iteration-test.ar
Normal file
3
tests/iteration-test.ar
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
let i = 1e6
|
||||||
|
while (i) do
|
||||||
|
i = i-1
|
||||||
Reference in New Issue
Block a user