Skip to content

Commit

Permalink
Merge pull request #9 from loumadev/expressionParser
Browse files Browse the repository at this point in the history
Expression parser
  • Loading branch information
loumadev authored Nov 19, 2023
2 parents 47344ed + 6236fad commit 97125ac
Show file tree
Hide file tree
Showing 23 changed files with 3,215 additions and 184 deletions.
2 changes: 2 additions & 0 deletions include/allocator/MemoryAllocator.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,15 @@ enum AllocatorAction {
MEMORY_ALLOC,
MEMORY_CALLOC,
MEMORY_REALLOC,
MEMORY_RECALLOC,
MEMORY_FREE,
MEMORY_CLEANUP
};

void* mem_alloc(size_t size);
void* mem_calloc(size_t nitems, size_t size);
void* mem_realloc(void *ptr, size_t size);
void* mem_recalloc(void *ptr, size_t oldNitems, size_t nitems, size_t size);
void mem_free(void *ptr);

void* safe_malloc(size_t size);
Expand Down
37 changes: 11 additions & 26 deletions include/compiler/Result.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
#include "internal/String.h"
#include "internal/Array.h"

#ifndef PARSER_H
#define PARSER_H
#ifndef RESULT_H
#define RESULT_H

enum Severity {
SEVERITY_NONE = 0,
Expand All @@ -12,35 +12,20 @@ enum Severity {
SEVERITY_INFO
};


/*
• 1 - chyba v programu v rámci lexikální analýzy (chybná struktura aktuálního lexému).
• 2 - chyba v programu v rámci syntaktické analýzy (chybná syntaxe programu, chybějící hlavička, atp.).
• 3 - sémantická chyba v programu – nedefinovaná funkce, pokus o redefinice funkce.
• 4 - sémantická/běhová chyba v programu – špatný počet/typ parametrů u volání funkce či typ návratové hodnoty z funkce.
• 5 - sémantická chyba v programu – použití nedefinované proměnné.
• 6 - sémantická/běhová chyba v programu – chybějící/přebývající výraz v příkazu návratu z funkce.
• 7 - sémantická/běhová chyba typové kompatibility v aritmetických, řetězcových a
relačních výrazech.
• 8 - ostatní sémantické chyby.
• 99 - interní chyba překladače tj. neovlivněná vstupním programem (např. chyba alokace paměti atd.).
*/
enum ResultType {
RESULT_INVALID = -3,
RESULT_NO_MATCH = -2,
RESULT_ASSERTION = -1,
RESULT_SUCCESS = 0,
RESULT_ERROR_STATIC_LEXICAL_ANALYSIS = 1,
RESULT_ERROR_STATIC_SYNTACTIC_ANALYSIS = 2,
// TODO: Add more error types
RESULT_ERROR_SEMANTIC_FUNCTION = 3,
RESULT_ERROR_RUNTIME_UNDEFINED_VARIABLE = 5,
RESULT_ERROR_SEMANTIC_OTHER = 8,
RESULT_ERROR_INTERNAL = 99
RESULT_ERROR_LEXICAL_ANALYSIS = 1, // Chybná struktura aktuálního lexému
RESULT_ERROR_SYNTACTIC_ANALYSIS = 2, // Chybná syntaxe programu, chybějící hlavička, atp.
RESULT_ERROR_SEMANTIC_FUNCTION_DEFINITION = 3, // Nedefinovaná funkce, pokus o redefinice funkce
RESULT_ERROR_SEMANTIC_INVALID_FUNCTION_CALL = 4, // Špatný počet/typ parametrů u volání funkce či typ návratové hodnoty z funkce
RESULT_ERROR_SEMANTIC_UNDEFINED_VARIABLE = 5, // Použití nedefinované proměnné
RESULT_ERROR_SEMANTIC_INVALID_RETURN = 6, // Chybějící/přebývající výraz v příkazu návratu z funkce
RESULT_ERROR_SEMANTIC_INVALID_TYPE = 7, // Chyba typové kompatibility v aritmetických, řetězcových a relačních výrazech
RESULT_ERROR_SEMANTIC_OTHER = 8, // Ostatní sémantické chyby
RESULT_ERROR_INTERNAL = 99 // Interní chyba překladače tj. neovlivněná vstupním programem (např. chyba alokace paměti atd.)
};

typedef struct Result {
Expand Down
2 changes: 1 addition & 1 deletion include/compiler/lexer/LexerResult.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,6 @@ LexerResult LexerResult_construct(

#define LexerSuccess() LexerResult_construct(RESULT_SUCCESS, SEVERITY_NONE, NULL, NULL, NULL)
#define LexerNoMatch() LexerResult_construct(RESULT_NO_MATCH, SEVERITY_NONE, NULL, NULL, NULL)
#define LexerError(message, markers) LexerResult_construct(RESULT_ERROR_STATIC_LEXICAL_ANALYSIS, SEVERITY_ERROR, message, markers, NULL)
#define LexerError(message, markers) LexerResult_construct(RESULT_ERROR_LEXICAL_ANALYSIS, SEVERITY_ERROR, message, markers, NULL)

#endif
22 changes: 15 additions & 7 deletions include/compiler/lexer/Token.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ enum TokenType {
TOKEN_EOF = 1,
TOKEN_CONTROL, // Forgot what this is for :(
TOKEN_MARKER, // Marker in the source code (for error messages)
TOKEN_STRING_INTERPOLATION_MARKER,

TOKEN_LITERAL,
TOKEN_IDENTIFIER,
Expand All @@ -21,6 +22,9 @@ enum TokenKind {
TOKEN_DEFAULT = 0,

// Literals
// This has to be at this position in the enum
// because it's being converted into another
// enum with the same values.
TOKEN_STRING,
TOKEN_INTEGER,
TOKEN_FLOATING,
Expand Down Expand Up @@ -67,13 +71,13 @@ enum TokenKind {
enum WhitespaceType {
WHITESPACE_NONE = 0, // No whitespace

// WHITESPACE_LEFT_LIMIT = 1 << 0, // BOF or EOF
WHITESPACE_LEFT_SPACE = 1 << 1, // Space, tab, or vertical tab
WHITESPACE_LEFT_NEWLINE = 1 << 2, // Line feed or carriage return
// WHITESPACE_LEFT_LIMIT = 1 << 0, // BOF or EOF
WHITESPACE_LEFT_SPACE = 1 << 1, // Space, tab, vertical tab or multi-line comment on a single line
WHITESPACE_LEFT_NEWLINE = 1 << 2, // Line feed, carriage return, multi-line comment on multiple lines or single-line comment

// WHITESPACE_RIGHT_LIMIT = 1 << 4, // BOF or EOF
WHITESPACE_RIGHT_SPACE = 1 << 5, // Space, tab, or vertical tab
WHITESPACE_RIGHT_NEWLINE = 1 << 6, // Line feed or carriage return
// WHITESPACE_RIGHT_LIMIT = 1 << 4, // BOF or EOF
WHITESPACE_RIGHT_SPACE = 1 << 5, // Space, tab, vertical tab or multi-line comment on a single line
WHITESPACE_RIGHT_NEWLINE = 1 << 6, // Line feed, carriage return, multi-line comment on multiple lines or single-line comment

WHITESPACE_LEFT = WHITESPACE_LEFT_SPACE | WHITESPACE_LEFT_NEWLINE,
WHITESPACE_RIGHT = WHITESPACE_RIGHT_SPACE | WHITESPACE_RIGHT_NEWLINE,
Expand All @@ -83,7 +87,11 @@ enum WhitespaceType {
WHITESPACE_MASK_RIGHT = /*WHITESPACE_RIGHT_LIMIT |*/ WHITESPACE_RIGHT_SPACE | WHITESPACE_RIGHT_NEWLINE
};

#define whitespace_both(whitespace) (((whitespace) & WHITESPACE_LEFT) && ((whitespace) & WHITESPACE_RIGHT))
#define whitespace_left(whitespace) ((whitespace) & WHITESPACE_LEFT)
#define whitespace_right(whitespace) ((whitespace) & WHITESPACE_RIGHT)
#define whitespace_both(whitespace) (whitespace_left(whitespace) && whitespace_right(whitespace))
#define whitespace_none(whitespace) ((whitespace) == WHITESPACE_NONE)
#define whitespace_consistent(whitespace) (whitespace_both(whitespace) || whitespace_none(whitespace))

#define right_to_left_whitespace(whitespace) (((whitespace) & WHITESPACE_RIGHT) >> 4)
#define left_to_right_whitespace(whitespace) (((whitespace) & WHITESPACE_LEFT) << 4)
Expand Down
180 changes: 156 additions & 24 deletions include/compiler/parser/ASTNodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#include "internal/Array.h"
#include "internal/String.h"
#include "compiler/lexer/Token.h"

#ifndef ASTNode_H
#define ASTNode_H
Expand All @@ -13,15 +14,52 @@ enum ASTNodeType {
NODE_IDENTIFIER,
NODE_TYPE_REFERENCE,
NODE_VARIABLE_DECLARATION,
NODE_VARIABLE_DECLARATION_LIST,
NODE_VARIABLE_DECLARATOR,
NODE_EXPRESSION_STATEMENT,
NODE_RETURN_STATEMENT,
NODE_PARAMETER,
NODE_PARAMETER_LIST,
NODE_FUNCTION_DECLARATION,
NODE_ARGUMENT,
NODE_FUNCTION_CALL
NODE_BINARY_EXPRESSION,
NODE_UNARY_EXPRESSION,
NODE_LITERAL_EXPRESSION,
NODE_ARGUMENT_LIST,
NODE_FUNCTION_CALL,
NODE_IF_STATEMENT,
NODE_PATTERN,
NODE_CONDITION,
NODE_OPTIONAL_BINDING_CONDITION,
NODE_WHILE_STATEMENT,
NODE_ASSIGNMENT_STATEMENT
};

typedef enum OperatorType {
OPERATOR_DEFAULT = 0,
OPERATOR_PLUS,
OPERATOR_MINUS,
OPERATOR_MUL,
OPERATOR_DIV,
OPERATOR_UNWRAP,
OPERATOR_NULL_COALESCING,
OPERATOR_EQUAL,
OPERATOR_NOT_EQUAL,
OPERATOR_LESS,
OPERATOR_GREATER,
OPERATOR_LESS_EQUAL,
OPERATOR_GREATER_EQUAL
} OperatorType;

typedef enum LiteralType {
LITERAL_INVALID = 0,
LITERAL_STRING,
LITERAL_INTEGER,
LITERAL_FLOATING,
LITERAL_BOOLEAN,
LITERAL_NIL
} LiteralType;


/* Definition of AST nodes */

Expand Down Expand Up @@ -53,10 +91,21 @@ typedef struct TypeReferenceASTNode {
bool isNullable;
} TypeReferenceASTNode;

typedef struct VariableDeclaratorASTNode {
enum ASTNodeType _type;
struct PatternASTNode *pattern;
ExpressionASTNode *initializer;
} VariableDeclaratorASTNode;

typedef struct VariableDeclarationListASTNode {
enum ASTNodeType _type;
Array /*<VariableDeclaratorASTNode>*/ *declarators;
} VariableDeclarationListASTNode;

typedef struct VariableDeclarationASTNode {
enum ASTNodeType _type;
IdentifierASTNode *id;
TypeReferenceASTNode *type;
VariableDeclarationListASTNode *declaratorList;
bool isConstant;
} VariableDeclarationASTNode;

typedef struct ExpressionStatementASTNode {
Expand All @@ -71,10 +120,10 @@ typedef struct ReturnStatementASTNode {

typedef struct ParameterASTNode {
enum ASTNodeType _type;
IdentifierASTNode *id;
IdentifierASTNode *internalId;
TypeReferenceASTNode *type;
ExpressionASTNode *initializer;
IdentifierASTNode *externalName;
IdentifierASTNode *externalId;
bool isLabeless;
} ParameterASTNode;

Expand All @@ -83,12 +132,6 @@ typedef struct ParameterListASTNode {
Array /*<ParameterASTNode>*/ *parameters;
} ParameterListASTNode;

typedef struct ArgumentASTNode {
enum ASTNodeType _type;
ExpressionASTNode *expression;
IdentifierASTNode *label;
} ArgumentASTNode;

typedef struct FunctionDeclarationASTNode {
enum ASTNodeType _type;
IdentifierASTNode *id;
Expand All @@ -97,35 +140,124 @@ typedef struct FunctionDeclarationASTNode {
BlockASTNode *body;
} FunctionDeclarationASTNode;

typedef struct ArgumentASTNode {
enum ASTNodeType _type;
ExpressionASTNode *expression;
IdentifierASTNode *label;
} ArgumentASTNode;

typedef struct ArgumentListASTNode {
enum ASTNodeType _type;
Array /*<ArgumentASTNode>*/ *arguments;
} ArgumentListASTNode;

typedef struct FunctionCallASTNode {
enum ASTNodeType _type;
IdentifierASTNode *id;
Array /*<ArgumentASTNode>*/ *arguments;
ArgumentListASTNode *argumentList;
} FunctionCallASTNode;

// typedef struct ExpressionASTNode {
// enum ASTNodeType _type;
// BinaryExpressionASTNode *BExpression;
// UnaryExpressionASTNode *UExpression;
// LiteralExpressionASTNode *LExpression;
// IdentifierASTNode *IExpression;
// } ExpressionASTNode;

typedef struct BinaryExpressionASTNode {
enum ASTNodeType _type;
ExpressionASTNode *left;
ExpressionASTNode *right;
OperatorType operator;
} BinaryExpressionASTNode;

typedef struct UnaryExpressionASTNode {
enum ASTNodeType _type;
ExpressionASTNode *argument;
OperatorType operator;
// bool isPrefix;
} UnaryExpressionASTNode;

typedef struct LiteralExpressionASTNode {
enum ASTNodeType _type;
LiteralType type;
union TokenValue value;
} LiteralExpressionASTNode;

typedef struct PatternASTNode {
enum ASTNodeType _type;
IdentifierASTNode *id;
TypeReferenceASTNode *type;
} PatternASTNode;

typedef struct OptionalBindingConditionASTNode {
enum ASTNodeType _type;
PatternASTNode *pattern;
ExpressionASTNode *initializer;
bool isConstant;
} OptionalBindingConditionASTNode;

typedef struct ConditionASTNode {
enum ASTNodeType _type;
ExpressionASTNode *expression;
OptionalBindingConditionASTNode *optionalBindingCondition;
} ConditionASTNode;

typedef struct IfStatementASTNode {
enum ASTNodeType _type;
ConditionASTNode *condition;
BlockASTNode *body;
ASTNode /* BlockASTNode | IfStatementASTNode | null */ *alternate;
} IfStatementASTNode;

typedef struct WhileStatementASTNode {
enum ASTNodeType _type;
ConditionASTNode *condition;
BlockASTNode *body;
} WhileStatementASTNode;

typedef struct AssignmentStatementASTNode {
enum ASTNodeType _type;
IdentifierASTNode *id;
ExpressionASTNode *assignment;
} AssignmentStatementASTNode;

// TODO: Add more AST nodes


/* Constructors for AST nodes */

ProgramASTNode * new_ProgramASTNode(BlockASTNode *block);
BlockASTNode * new_BlockASTNode(Array *statements);
IdentifierASTNode * new_IdentifierASTNode(String *name);
TypeReferenceASTNode * new_TypeReferenceASTNode(IdentifierASTNode *id, bool isNullable);
VariableDeclarationASTNode * new_VariableDeclarationASTNode(IdentifierASTNode *id, TypeReferenceASTNode *type);
ReturnStatementASTNode * new_ReturnStatementASTNode(ExpressionASTNode *expression);
ParameterASTNode * new_ParameterASTNode(IdentifierASTNode *id, TypeReferenceASTNode *type, ExpressionASTNode *initializer, IdentifierASTNode *externalName, bool isLabeless);
ParameterListASTNode * new_ParameterListASTNode(Array *parameters);
ArgumentASTNode * new_ArgumentASTNode(ExpressionASTNode *expression, IdentifierASTNode *label);
FunctionDeclarationASTNode * new_FunctionDeclarationASTNode(IdentifierASTNode *id, ParameterListASTNode *parameterList, TypeReferenceASTNode *returnType, BlockASTNode *body);
FunctionCallASTNode * new_FunctionCallASTNode(IdentifierASTNode *id, Array *arguments);
ProgramASTNode* new_ProgramASTNode(BlockASTNode *block);
BlockASTNode* new_BlockASTNode(Array *statements);
IdentifierASTNode* new_IdentifierASTNode(String *name);
TypeReferenceASTNode* new_TypeReferenceASTNode(IdentifierASTNode *id, bool isNullable);
VariableDeclarationASTNode* new_VariableDeclarationASTNode(VariableDeclarationListASTNode *declaratorList, bool isConstant);
VariableDeclaratorASTNode* new_VariableDeclaratorASTNode(PatternASTNode *pattern, ExpressionASTNode *initializer);
VariableDeclarationListASTNode* new_VariableDeclarationListASTNode(Array *declarators);
ReturnStatementASTNode* new_ReturnStatementASTNode(ExpressionASTNode *expression);
ParameterASTNode* new_ParameterASTNode(IdentifierASTNode *internalId, TypeReferenceASTNode *type, ExpressionASTNode *initializer, IdentifierASTNode *externalId, bool isLabeless);
ParameterListASTNode* new_ParameterListASTNode(Array *parameters);
FunctionDeclarationASTNode* new_FunctionDeclarationASTNode(IdentifierASTNode *id, ParameterListASTNode *parameterList, TypeReferenceASTNode *returnType, BlockASTNode *body);
BinaryExpressionASTNode* new_BinaryExpressionASTNode(ExpressionASTNode *left, ExpressionASTNode *right, OperatorType operator);
UnaryExpressionASTNode* new_UnaryExpressionASTNode(ExpressionASTNode *argument, OperatorType operator /*, bool isPrefix*/);
LiteralExpressionASTNode* new_LiteralExpressionASTNode(LiteralType type, union TokenValue value);
ArgumentASTNode* new_ArgumentASTNode(ExpressionASTNode *expression, IdentifierASTNode *label);
ArgumentListASTNode* new_ArgumentListASTNode(Array *arguments);
FunctionCallASTNode* new_FunctionCallASTNode(IdentifierASTNode *id, ArgumentListASTNode *argumentList);
PatternASTNode* new_PatternASTNode(IdentifierASTNode *id, TypeReferenceASTNode *type);
OptionalBindingConditionASTNode* new_OptionalBindingConditionASTNode(PatternASTNode *pattern, ExpressionASTNode *initializer, bool isConstant);
ConditionASTNode* new_ConditionASTNode(ExpressionASTNode *expression, OptionalBindingConditionASTNode *optionalBindingCondition);
IfStatementASTNode* new_IfStatementASTNode(ConditionASTNode *condition, BlockASTNode *body, ASTNode *alternate);
WhileStatementASTNode* new_WhileStatementASTNode(ConditionASTNode *condition, BlockASTNode *body);
AssignmentStatementASTNode* new_AssignmentStatementASTNode(IdentifierASTNode *id, ExpressionASTNode *assignment);

// TODO: Add more AST node constructors


/* Other public functions */

ASTNode * ASTNode_alloc(size_t size, enum ASTNodeType type);
ASTNode* ASTNode_alloc(size_t size, enum ASTNodeType type);
void ASTNode_free(ASTNode *node);

void ASTNode_print(ASTNode *node);
Expand Down
Loading

0 comments on commit 97125ac

Please sign in to comment.