libmya 0.1.0
Library to parse Mya language.
Loading...
Searching...
No Matches
parse_expression.c File Reference
#include <stdbool.h>
#include "ast.h"
#include "aststack.h"
#include "module.h"
#include "parser.h"
#include "tkqueue.h"
#include "tkstack.h"
#include "types/operators.h"
Include dependency graph for parse_expression.c:

Go to the source code of this file.

Functions

unsigned int parse_expression (module_t *module, ast_node_t *parent, token_t *token)
 Parse a mathematical expression adding it as a children on parent AST node.
 

Function Documentation

◆ parse_expression()

unsigned int parse_expression ( module_t * module,
ast_node_t * parent,
token_t * token )

Parse a mathematical expression adding it as a children on parent AST node.

Parameters
moduleThe module where the AST is.
parentThe AST node parent for the expression.
tokenThe token where to start parsing the expression.
Returns
The number of tokens used on the expression.

Definition at line 24 of file parse_expression.c.

25{
27 tkqueue_t queue;
28 token_t* current_token;
29 bool is_unary = false;
30 unsigned int ntokens = 0;
31
33 return parse_bitfield_spec(module, parent, token);
34 }
35
37 tkqueue_init(&queue, 30);
38
39 for (;;) {
40 current_token = &token[ntokens++];
41
42 switch (current_token->type) {
43 case TK_OPEN_PARENS:
44 tkstack_push(&stack, current_token);
45 is_unary = true;
46 break;
47 case TK_IDENTIFIER:
48 case TK_NUMBER:
49 tkqueue_add(&queue, current_token);
50 is_unary = false;
51 break;
52 case TK_EQUAL:
53 ntokens = _parse_bitfield_expression(module, parent, &queue, current_token);
54 goto clean_and_exit;
55 case TK_OPERATOR:
56 if (is_unary && current_token->value == OP_MINUS) {
57 current_token->value = OP_NEGATE;
58 }
59
60 while (! tkstack_isempty(&stack) && tkstack_peek(&stack)->type != TK_OPEN_PARENS &&
61 _op_precedence(tkstack_peek(&stack)) >= _op_precedence(current_token)) {
62 tkqueue_add(&queue, tkstack_pop(&stack));
63 }
64
65 tkstack_push(&stack, current_token);
66 is_unary = true;
67 break;
68 case TK_CLOSE_PARENS:
69 for (;;) {
70 token_t* popped = tkstack_pop(&stack);
71 if (! popped) {
73 module,
74 current_token->line,
75 current_token->column,
76 current_token->lexeme.length,
77 "Close parentheses here is not matching a open parentheses."
78 );
79
80 goto clean_and_exit;
81 }
82
83 if (popped->type == TK_OPEN_PARENS) {
84 break;
85 }
86
87 tkqueue_add(&queue, popped);
88 }
89
90 is_unary = false;
91 break;
92 case TK_SEMICOLON:
93 case TK_CLOSE_BRACES:
95 case TK_COMMA:
96 case TK_EOF:
97 ntokens--;
98 goto finish_expression;
99 default:
101 module,
102 current_token->line,
103 current_token->column,
104 current_token->lexeme.length,
105 "Unexpected token inside an expression."
106 );
107
108 ntokens++;
109 goto finish_expression;
110 }
111 }
112
113
114finish_expression:
115 while (! tkstack_isempty(&stack)) {
116 tkqueue_add(&queue, tkstack_pop(&stack));
117 }
118
119 _generate_ast(module, parent, &queue);
120
121clean_and_exit:
123 tkqueue_close(&queue);
124
125 return ntokens;
126}
void module_add_error(module_t *module, unsigned int line, unsigned int column, unsigned int length, const char *message)
Add error for the given module.
Definition module.c:119
@ OP_NEGATE
Definition operators.h:9
@ OP_MINUS
Definition operators.h:7
unsigned int parse_bitfield_spec(module_t *module, ast_node_t *parent, token_t *token)
Parse a bitfield specification in the format Bitfield { FIELD_LIST } or Bitfield { EXPRESSION }...
unsigned int length
The length of the string.
Definition dstring.h:13
Struct that represents a Mya module.
Definition module.h:36
A struct representing a dynamic stack.
Definition aststack.h:12
Struct for a Mya token.
Definition token.h:34
long long int value
Integer value of the token.
Definition token.h:38
token_type_t type
Token type.
Definition token.h:35
dstring_t lexeme
Lexeme of the token.
Definition token.h:41
unsigned int line
Token line inside the module.
Definition token.h:36
unsigned int column
Column of the token position on the line.
Definition token.h:37
void tkqueue_add(tkqueue_t *queue, token_t *token)
Add a value to the token queue.
Definition tkqueue.c:25
void tkqueue_init(tkqueue_t *queue, unsigned int initial_size)
Initializes the token queue.
Definition tkqueue.c:9
void tkqueue_close(tkqueue_t *queue)
Close the given queue.
Definition tkqueue.c:18
token_t * tkstack_peek(tkstack_t *stack)
Peeks the value on top of the stack without removing it.
Definition tkstack.c:45
bool tkstack_isempty(tkstack_t *stack)
Check if the given stack is empty.
Definition tkstack.c:55
token_t * tkstack_pop(tkstack_t *stack)
Pop a value from the stack.
Definition tkstack.c:35
void tkstack_close(tkstack_t *stack)
Closes the given stack.
Definition tkstack.c:20
void tkstack_init(tkstack_t *stack)
Initializes the given stack.
Definition tkstack.c:11
void tkstack_push(tkstack_t *stack, token_t *token)
Push a new value on the stack.
Definition tkstack.c:27
struct tkqueue tkqueue_t
Queue of tokens.
struct tkstack tkstack_t
A struct representing a dynamic stack of token_t pointers.
struct token token_t
Struct for a Mya token.
@ TK_NUMBER
Definition token.h:21
@ TK_IDENTIFIER
Definition token.h:19
@ TK_OPEN_BRACES
Definition token.h:22
@ TK_OPEN_PARENS
Definition token.h:24
@ TK_COMMA
Definition token.h:16
@ TK_CLOSE_PARENS
Definition token.h:14
@ TK_OPERATOR
Definition token.h:25
@ TK_CLOSE_BRACKET
Definition token.h:13
@ TK_EOF
Definition token.h:17
@ TK_CLOSE_BRACES
Definition token.h:12
@ TK_EQUAL
Definition token.h:18
@ TK_SEMICOLON
Definition token.h:26