add operations

This commit is contained in:
2025-06-10 04:41:06 +01:00
parent 1b90438bb9
commit 86c0eabfde
18 changed files with 207 additions and 68 deletions

26
.vscode/launch.json vendored Normal file
View File

@@ -0,0 +1,26 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "C/C++ Debug (gdb Launch)",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/bin/argon",
"args": ["test.ar"],
"stopAtEntry": true,
"cwd": "${workspaceFolder}",
"environment": [],
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
}
]
}

View File

@@ -3,7 +3,7 @@ LEXER_C = src/lexer/lex.yy.c
LEXER_H = src/lexer/lex.yy.h
CFILES = $(shell find src -name '*.c')
CFLAGS = -lm -lcjson -lgc -lgmp -Wall -Wextra -Wno-unused-function -s
CFLAGS = -lm -lcjson -lgc -lgmp -Wall -Wextra -Wno-unused-function
BINARY = bin/argon
all: $(BINARY)
@@ -13,12 +13,16 @@ $(LEXER_C) $(LEXER_H): $(LEXER_SRC)
$(BINARY): $(CFILES) $(LEXER_C) $(LEXER_H)
mkdir -p bin
gcc -O3 -o $(BINARY) $(CFILES) $(CFLAGS)
gcc -O3 -o $(BINARY) $(CFILES) $(CFLAGS) -s
debug: $(CFILES) $(LEXER_C) $(LEXER_H)
mkdir -p bin
gcc -g -O0 -o $(BINARY) $(CFILES) $(CFLAGS)
full-debug: $(CFILES) $(LEXER_C) $(LEXER_H)
mkdir -p bin
gcc -g -O0 -fsanitize=address -fno-omit-frame-pointer -o $(BINARY) $(CFILES) $(CFLAGS)
optimised: $(CFILES) $(LEXER_C) $(LEXER_H)
mkdir -p bin
gcc -O3 -fprofile-generate -o $(BINARY) $(CFILES) $(CFLAGS)

View File

@@ -21,22 +21,22 @@ typedef enum {
TOKEN_ASSIGN_CARET,
// Operators
TOKEN_AND, // &&
TOKEN_OR, // ||
TOKEN_NOT_IN, // not in
TOKEN_LE, // <=
TOKEN_GE, // >=
TOKEN_CARET, // ^ (Exponentiation)
TOKEN_STAR, // * (Multiplication)
TOKEN_SLASH, // / (Division)
TOKEN_FLOORDIV, // // (Floor Division)
TOKEN_MODULO, // % (Modulo)
TOKEN_PLUS, // + (Addition)
TOKEN_MINUS, // - (Subtraction)
TOKEN_LT, // <
TOKEN_GT, // >
TOKEN_NE, // !=
TOKEN_LE, // <=
TOKEN_GE, // >=
TOKEN_EQ, // ==
TOKEN_PLUS, // +
TOKEN_MINUS, // -
TOKEN_MODULO, // %
TOKEN_STAR, // *
TOKEN_FLOORDIV, // //
TOKEN_SLASH, // /
TOKEN_CARET, // ^
TOKEN_NE, // !=
TOKEN_NOT_IN, // not in (Usually treated like a comparison)
TOKEN_AND, // &&
TOKEN_OR, // ||
// Keywords
TOKEN_IF,

View File

@@ -16,8 +16,8 @@ ParsedValue *parse_assign(char *file, DArray *tokens, ParsedValue *assign_to,
break;
case AST_CALL:;
ParsedCall *call = assign_to->data;
for (size_t i = 0; i < call->args->size; i++) {
if (((ParsedValue *)darray_get(call->args, i))->type != AST_IDENTIFIER) {
for (size_t i = 0; i < call->args.size; i++) {
if (((ParsedValue *)darray_get(&call->args, i))->type != AST_IDENTIFIER) {
fprintf(stderr,
"%s:%zu:%zu error: parameter names need to start with a letter "
"or _, "

View File

@@ -13,8 +13,7 @@ ParsedValue *parse_call(char *file, DArray *tokens, size_t *index,
call->to_call = to_call;
parsedValue->data = call;
parsedValue->type = AST_CALL;
call->args = checked_malloc(sizeof(DArray));
darray_init(call->args, sizeof(ParsedValue));
darray_init(&call->args, sizeof(ParsedValue));
(*index)++;
error_if_finished(file, tokens, index);
Token *token = darray_get(tokens, *index);
@@ -23,7 +22,7 @@ ParsedValue *parse_call(char *file, DArray *tokens, size_t *index,
skip_newlines_and_indents(tokens, index);
error_if_finished(file, tokens, index);
ParsedValue *parsedArg = parse_token(file, tokens, index, true);
darray_push(call->args, parsedArg);
darray_push(&call->args, parsedArg);
free(parsedArg);
error_if_finished(file, tokens, index);
skip_newlines_and_indents(tokens, index);
@@ -48,7 +47,7 @@ void free_parse_call(void *ptr) {
ParsedValue *parsedValue = ptr;
ParsedCall *parsedCall = parsedValue->data;
darray_free(parsedCall->args, free_parsed);
darray_free(&parsedCall->args, free_parsed);
free_parsed(parsedCall->to_call);
free(parsedCall);
}

View File

@@ -5,7 +5,7 @@
typedef struct {
ParsedValue * to_call;
DArray * args;
DArray args;
} ParsedCall;
// Function declaration for parsing an identifier

View File

@@ -1,5 +1,3 @@
// parser.h
#ifndef IDENTIFIER_H
#define IDENTIFIER_H
#include "../../parser.h"

View File

@@ -39,8 +39,7 @@ ParsedValue *parse_declaration(char *file, DArray *tokens, size_t *index) {
token = darray_get(tokens, *index);
if (token->type == TOKEN_LPAREN) {
declaration->is_function = true;
declaration->parameters = checked_malloc(sizeof(DArray));
darray_init(declaration->parameters, sizeof(char *));
darray_init(&declaration->parameters, sizeof(char *));
(*index)++;
error_if_finished(file, tokens, index);
token = darray_get(tokens, *index);
@@ -62,7 +61,7 @@ ParsedValue *parse_declaration(char *file, DArray *tokens, size_t *index) {
}
char *parameter_name =
strcpy(checked_malloc(strlen(token->value) + 1), token->value);
darray_push(declaration->parameters, &parameter_name);
darray_push(&declaration->parameters, &parameter_name);
(*index)++;
error_if_finished(file, tokens, index);
skip_newlines_and_indents(tokens, index);
@@ -127,7 +126,7 @@ void free_single_declaration(void *ptr) {
ParsedSingleDeclaration *declaration = ptr;
free(declaration->name);
if (declaration->is_function)
darray_free(declaration->parameters, free_string);
darray_free(&declaration->parameters, free_string);
free_parsed(declaration->from);
free(declaration->from);
}

View File

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

View File

@@ -48,8 +48,6 @@ ParsedValue *parse_dowrap(char *file, DArray *tokens, size_t *index) {
DArray to_free;
darray_init(&to_free, sizeof(char *));
size_t starting_index = *index;
size_t temp_index_count = 0;
while (!pass && ++(*index) < tokens->size) {

View File

@@ -35,7 +35,7 @@ ParsedValue *parse_if(char *file, DArray *tokens, size_t *index) {
}
}
DArray *condition = NULL;
ParsedValue *condition = NULL;
if (token->type != TOKEN_ELSE) {
// Parse ( condition )
@@ -48,22 +48,11 @@ ParsedValue *parse_if(char *file, DArray *tokens, size_t *index) {
(*index)++;
error_if_finished(file, tokens, index);
condition = checked_malloc(sizeof(DArray));
darray_init(condition, sizeof(ParsedValue));
while (*index < tokens->size) {
ParsedValue *parsed_code = parse_token(file, tokens, index, true);
if (parsed_code) {
darray_push(condition, parsed_code);
free(parsed_code);
}
skip_newlines_and_indents(tokens, index);
condition = parse_token(file, tokens, index, true);
skip_newlines_and_indents(tokens, index);
token = darray_get(tokens, *index);
if (token->type == TOKEN_RPAREN)
break;
}
if (token->type != TOKEN_RPAREN) {
fprintf(stderr, "%s:%zu:%zu error: missing closing ')' in condition\n",
file, token->line, token->column);
@@ -114,8 +103,10 @@ ParsedValue *parse_if(char *file, DArray *tokens, size_t *index) {
void free_conditional(void *ptr) {
ParsedConditional *conditional = ptr;
if (conditional->condition)
darray_free(conditional->condition, free_parsed);
if (conditional->condition) {
free_parsed(conditional->condition);
free(conditional->condition);
}
free_parsed(conditional->content);
free(conditional->content);
}
@@ -124,4 +115,5 @@ void free_parsed_if(void *ptr) {
ParsedValue *parsedValue = ptr;
DArray *parsed_if = parsedValue->data;
darray_free(parsed_if, free_conditional);
free(parsedValue->data);
}

View File

@@ -1,12 +1,10 @@
// parser.h
#ifndef iF_H
#define iF_H
#include "../../lexer/token.h" // for Token
#include "../parser.h"
typedef struct {
DArray *condition; // NULL for 'else'
ParsedValue * condition; // NULL for 'else'
ParsedValue *content;
} ParsedConditional;

View File

@@ -1,5 +1,3 @@
// parser.h
#ifndef NUMBER_H
#define NUMBER_H
#include "../parser.h"

View File

@@ -0,0 +1,81 @@
#include "operations.h"
#include "../parser.h"
#include "../../memory.h"
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
ParsedValue *convert_to_operation(DArray * to_operate_on, DArray * operations) {
if (to_operate_on->size == 1) {
return darray_get(to_operate_on, 0);
}
TokenType operation = 0;
DArray positions;
for (size_t i = 0; i<operations->size;i++) {
TokenType * current_operation = darray_get(operations, i);
if (operation < *current_operation) {
if (operation!=0) {
darray_free(&positions, NULL);
}
operation = *current_operation;
darray_init(&positions, sizeof(size_t));
}
darray_push(&positions, &i);
}
size_t last_position = operations->size-1;
darray_push(&positions, &last_position);
ParsedValue * parsedValue = checked_malloc(sizeof(ParsedValue));
parsedValue->type = AST_OPERATION;
ParsedOperation * operationStruct = checked_malloc(sizeof(ParsedOperation));
parsedValue->data = operationStruct;
operationStruct->operation = operation;
darray_init(&operationStruct->to_operate_on, sizeof(ParsedValue));
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, last_position, *position+1);
DArray operations_slice = darray_slice(operations, last_position, *position);
darray_push(&operationStruct->to_operate_on, convert_to_operation(&to_operate_on_slice, &operations_slice));
last_position = *position;
}
darray_free(&positions, NULL);
return parsedValue;
}
ParsedValue *parse_operations(char *file, DArray *tokens, size_t *index,
ParsedValue *first_parsed_value) {
DArray to_operate_on;
darray_init(&to_operate_on, sizeof(ParsedValue));
darray_push(&to_operate_on, first_parsed_value);
DArray operations;
darray_init(&operations, sizeof(TokenType));
while (tokens->size > *index) {
bool to_break = false;
Token *token = darray_get(tokens, *index);
switch (token->type) {
SWITCH_OPERATIONS
break;
default:
to_break = true;
}
if (to_break)
break;
darray_push(&operations, &token->type);
(*index)++;
error_if_finished(file, tokens, index);
darray_push(&to_operate_on, parse_token_full(file, tokens, index, true, false));
}
ParsedValue *output = convert_to_operation(&to_operate_on, &operations);
darray_free(&to_operate_on, free_parsed);
darray_free(&operations, free_parsed);
return output;
}
void free_operation(void *ptr) {
ParsedValue *parsedValue = ptr;
ParsedOperation *parsed_operation = parsedValue->data;
darray_free(&parsed_operation->to_operate_on, free_parsed);
free(parsed_operation);
}

View File

@@ -0,0 +1,15 @@
#ifndef OPERATIONS_H
#define OPERATIONS_H
#include "../parser.h"
#include "../../lexer/token.h" // for Token
typedef struct {
TokenType operation;
DArray to_operate_on; // ParsedValue[]
} ParsedOperation;
ParsedValue *parse_operations(char*file,DArray *tokens, size_t * index, ParsedValue * first_parsed_value);
void free_operation(void *ptr);
#endif // OPERATIONS_H

View File

@@ -6,6 +6,7 @@
#include "assignable/call/call.h"
#include "assignable/identifier/identifier.h"
#include "declaration/declaration.h"
#include "operations/operations.h"
#include "dowrap/dowrap.h"
#include "if/if.h"
#include "literals/literals.h"
@@ -19,7 +20,7 @@
const char *ValueTypeNames[] = {
"string", "assign", "identifier", "number", "if statement", "access",
"call", "declaration", "null", "boolean", "do wrap"};
"call", "declaration", "null", "boolean", "do wrap", "operations"};
void error_if_finished(char *file, DArray *tokens, size_t *index) {
if ((*index) >= tokens->size) {
@@ -48,8 +49,8 @@ size_t skip_newlines_and_indents(DArray *tokens, size_t *index) {
return count;
}
ParsedValue *parse_token(char *file, DArray *tokens, size_t *index,
bool inline_flag) {
ParsedValue *parse_token_full(char *file, DArray *tokens, size_t *index,
bool inline_flag, bool process_operations) {
Token *token = darray_get(tokens, *index);
ParsedValue *output = NULL;
@@ -134,6 +135,12 @@ ParsedValue *parse_token(char *file, DArray *tokens, size_t *index,
case TOKEN_DOT:
output = parse_access(file, tokens, index, output);
break;
SWITCH_OPERATIONS
if (process_operations) {
output = parse_operations(file, tokens, index, output);
break;
}
/* fall through */
default:
passed = true;
}
@@ -142,6 +149,11 @@ ParsedValue *parse_token(char *file, DArray *tokens, size_t *index,
return output;
}
ParsedValue *parse_token(char *file, DArray *tokens, size_t *index,
bool inline_flag) {
return parse_token_full(file, tokens, index, inline_flag, true);
}
void parser(char *file, DArray *parsed, DArray *tokens, bool inline_flag) {
size_t index = 0;
bool expecting_new_line = false;
@@ -151,8 +163,8 @@ void parser(char *file, DArray *parsed, DArray *tokens, bool inline_flag) {
if (parsed_code) {
if (expecting_new_line) {
Token *token = darray_get(tokens, old_index);
fprintf(stderr, "%s:%zu:%zu error: syntax error\n", file, token->line,
token->column);
fprintf(stderr, "%s:%zu:%zu error: expected a new line\n", file,
token->line, token->column);
exit(EXIT_FAILURE);
}
expecting_new_line = true;
@@ -190,6 +202,9 @@ void free_parsed(void *ptr) {
case AST_IF:
free_parsed_if(parsed);
break;
case AST_OPERATION:
free_operation(parsed);
break;
case AST_DOWRAP:
free_dowrap(parsed);
break;

View File

@@ -5,6 +5,23 @@
#include <stdbool.h>
#include <stddef.h>
#define SWITCH_OPERATIONS case TOKEN_AND:\
case TOKEN_OR:\
case TOKEN_NOT_IN:\
case TOKEN_LE:\
case TOKEN_GE:\
case TOKEN_LT:\
case TOKEN_GT:\
case TOKEN_NE:\
case TOKEN_EQ:\
case TOKEN_PLUS:\
case TOKEN_MINUS:\
case TOKEN_MODULO:\
case TOKEN_STAR:\
case TOKEN_FLOORDIV:\
case TOKEN_SLASH:\
case TOKEN_CARET:
typedef struct LinkedList LinkedList;
typedef enum {
@@ -18,7 +35,8 @@ typedef enum {
AST_DECLARATION,
AST_NULL,
AST_BOOLEAN,
AST_DOWRAP
AST_DOWRAP,
AST_OPERATION
} ValueType;
extern const char* ValueTypeNames[];
@@ -30,8 +48,11 @@ typedef struct {
void parser(char *file, DArray *parsed, DArray *tokens, bool inline_flag);
ParsedValue *parse_token(char *file, DArray *tokens,
size_t *index, bool inline_flag);
ParsedValue *parse_token_full(char *file, DArray *tokens, size_t *index,
bool inline_flag, bool process_operations);
ParsedValue *parse_token(char *file, DArray *tokens, size_t *index,
bool inline_flag);
void free_parsed(void *ptr);

View File

@@ -40,9 +40,4 @@ else term.log("bruh")
mm
mm = 10*10 - 10