Skip to content

Commit

Permalink
Add variable declaration parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
mifka01 committed Oct 22, 2023
1 parent 81e315e commit 7302768
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 22 deletions.
30 changes: 22 additions & 8 deletions include/compiler/parser/ASTNodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ 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,
Expand All @@ -26,7 +28,7 @@ enum ASTNodeType {
NODE_PATTERN,
NODE_CONDITION,
NODE_OPTIONAL_BINDING_CONDITION,
NODE_WHILE_STATEMENT,
NODE_WHILE_STATEMENT
};


Expand Down Expand Up @@ -60,11 +62,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;
bool isConstant;
VariableDeclarationListASTNode *declaratorList;
bool isConstant;
} VariableDeclarationASTNode;

typedef struct ExpressionStatementASTNode {
Expand Down Expand Up @@ -113,7 +125,7 @@ typedef struct ArgumentListASTNode {
typedef struct FunctionCallASTNode {
enum ASTNodeType _type;
IdentifierASTNode *id;
ArgumentListASTNode* argumentList;
ArgumentListASTNode *argumentList;
} FunctionCallASTNode;

typedef struct PatternASTNode {
Expand All @@ -126,7 +138,7 @@ typedef struct OptionalBindingConditionASTNode {
enum ASTNodeType _type;
PatternASTNode *pattern;
ExpressionASTNode *initializer;
bool isConstant;
bool isConstant;
} OptionalBindingConditionASTNode;

typedef struct ConditionASTNode {
Expand Down Expand Up @@ -164,13 +176,15 @@ 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, bool isConstant);
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 *id, TypeReferenceASTNode *type, ExpressionASTNode *initializer, IdentifierASTNode *externalName, bool isLabeless);
ParameterListASTNode * new_ParameterListASTNode(Array *parameters);
FunctionDeclarationASTNode * new_FunctionDeclarationASTNode(IdentifierASTNode *id, ParameterListASTNode *parameterList, TypeReferenceASTNode *returnType, BlockASTNode *body);
ArgumentASTNode * new_ArgumentASTNode(ExpressionASTNode *expression, IdentifierASTNode *label);
ArgumentListASTNode * new_ArgumentListASTNode(Array * arguments);
ArgumentListASTNode * new_ArgumentListASTNode(Array *arguments);
FunctionCallASTNode * new_FunctionCallASTNode(IdentifierASTNode *id, ArgumentListASTNode *argumentList);
PatternASTNode * new_PatternASTNode(IdentifierASTNode *name, TypeReferenceASTNode *type);
OptionalBindingConditionASTNode * new_OptionalBindingConditionASTNode(PatternASTNode *pattern, ExpressionASTNode *initializer, bool isConstant);
Expand Down
25 changes: 21 additions & 4 deletions src/compiler/parser/ASTNodes.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,18 +41,35 @@ TypeReferenceASTNode * new_TypeReferenceASTNode(
return node;
}

VariableDeclaratorASTNode * new_VariableDeclaratorASTNode(
PatternASTNode *pattern,
ExpressionASTNode *initializer
) {
prepare_node_of(VariableDeclaratorASTNode, NODE_VARIABLE_DECLARATOR)
node->pattern = pattern;
node->initializer = initializer;
return node;
}

VariableDeclarationListASTNode * new_VariableDeclarationListASTNode(
Array *declarators
) {
prepare_node_of(VariableDeclarationListASTNode, NODE_VARIABLE_DECLARATION_LIST)
node->declarators = declarators;
return node;
}

VariableDeclarationASTNode * new_VariableDeclarationASTNode(
IdentifierASTNode *id,
TypeReferenceASTNode *type,
VariableDeclarationListASTNode *declaratorList,
bool isConstant
) {
prepare_node_of(VariableDeclarationASTNode, NODE_VARIABLE_DECLARATION)
node->id = id;
node->type = type;
node->declaratorList = declaratorList;
node->isConstant = isConstant;
return node;
}


ExpressionStatementASTNode * new_ExpressionStatementASTNode(
ExpressionASTNode *expression
) {
Expand Down
90 changes: 80 additions & 10 deletions src/compiler/parser/Parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ ParserResult __Parser_parseElseClause(Parser *parser);
ParserResult __Parser_parseIfStatement(Parser *parser);
ParserResult __Parser_parseWhileStatement(Parser *parser);
ParserResult __Parser_parseReturnStatement(Parser *parser);
ParserResult __Parser_parseVariableDeclarator(Parser *parser);
ParserResult __Parser_parseVariableDeclarationList(Parser *parser);
ParserResult __Parser_parseVariableDeclarationStatement(Parser *parser);
ParserResult __Parser_parseArgument(Parser *parser);
ParserResult __Parser_parseArgumentList(Parser *parser);
ParserResult __Parser_parseFunctionCallExpression(Parser *parser);
Expand Down Expand Up @@ -145,17 +148,12 @@ ParserResult __Parser_parseStatement(Parser *parser) {
return ParserSuccess(returnResult.node);
}

if(peek.token->type == TOKEN_IDENTIFIER) {
LexerResult peek = Lexer_peekToken(parser->lexer, 1);
if(!peek.success) return LexerToParserError(peek);

// function call
if(peek.token->kind == TOKEN_LEFT_PAREN) {
ParserResult functionCallResult = __Parser_parseFunctionCallExpression(parser);
if(!functionCallResult.success) return functionCallResult;
return ParserSuccess(functionCallResult.node);
}
if(peek.token->kind == TOKEN_LET || peek.token->kind == TOKEN_VAR) {
ParserResult variableDeclarationResult = __Parser_parseVariableDeclarationStatement(parser);
if(!variableDeclarationResult.success) return variableDeclarationResult;
return ParserSuccess(variableDeclarationResult.node);
}

return ParserNoMatch();
}

Expand Down Expand Up @@ -584,6 +582,78 @@ ParserResult __Parser_parseReturnStatement(Parser *parser) {
return ParserSuccess(returnStatement);
}


ParserResult __Parser_parseVariableDeclarator(Parser *parser) {
assertf(parser != NULL);

ParserResult patternResult = __Parser_parsePattern(parser);
if(!patternResult.success) return patternResult;

LexerResult peek = Lexer_peekToken(parser->lexer, 1);
if(!peek.success) return LexerToParserError(peek);

ExpressionASTNode *initializer = NULL;

if(peek.token->kind == TOKEN_EQUAL) {
ParserResult initializerResult = __Parser_parseExpression(parser);
if(!initializerResult.success) return initializerResult;
initializer = initializerResult.node;
}

VariableDeclaratorASTNode *variableDeclarator = new_VariableDeclaratorASTNode((PatternASTNode*)patternResult.node, (ExpressionASTNode*)initializer);

return ParserSuccess(variableDeclarator);
}

ParserResult __Parser_parseVariableDeclarationList(Parser *parser) {
assertf(parser != NULL);
LexerResult peek;
LexerResult result;


Array *declarators = Array_alloc(0);
while(true) {
ParserResult declaratorResult = __Parser_parseVariableDeclarator(parser);
if(!declaratorResult.success) return declaratorResult;

Array_push(declarators, (VariableDeclaratorASTNode*)declaratorResult.node);

peek = Lexer_peekToken(parser->lexer, 1);

if(peek.token->kind == TOKEN_COMMA) {
result = Lexer_nextToken(parser->lexer);
if(!result.success) return LexerToParserError(result);

}

peek = Lexer_peekToken(parser->lexer, 1);
if(peek.token->type == TOKEN_EOF) {
result = Lexer_nextToken(parser->lexer);
if(!result.success) return LexerToParserError(result);
break;
}
}

VariableDeclarationListASTNode *variableDeclarationList = new_VariableDeclarationListASTNode(declarators);

return ParserSuccess(variableDeclarationList);
}

ParserResult __Parser_parseVariableDeclarationStatement(Parser *parser) {
assertf(parser != NULL);

// let/var
LexerResult result = Lexer_nextToken(parser->lexer);
if(!result.success) return LexerToParserError(result);
bool isConstant = result.token->kind == TOKEN_LET;

ParserResult declarationList = __Parser_parseVariableDeclarationList(parser);
if(!declarationList.success) return declarationList;

VariableDeclarationASTNode *variableDeclaration = new_VariableDeclarationASTNode((VariableDeclarationListASTNode*)declarationList.node, isConstant);
return ParserSuccess(variableDeclaration);
}

ParserResult __Parser_parseArgument(Parser *parser) {
assertf(parser != NULL);

Expand Down

0 comments on commit 7302768

Please sign in to comment.