libmya 0.1.0
Library to parse Mya language.
Loading...
Searching...
No Matches
parse_expression.c
Go to the documentation of this file.
1#include "ast.h"
2#include "module.h"
3#include "parser.h"
4#include "stack.h"
5#include "types/operators.h"
6
7static unsigned int
8_parse_operator(module_t* module, ast_node_t* parent, stack_t* stack, token_t* token);
9
10static unsigned int
11_parse_binary_operator(module_t* module, ast_node_t* parent, stack_t* stack, token_t* token);
12
13static unsigned int
14_parse_unary_operator(module_t* module, ast_node_t* parent, stack_t* stack, token_t* token);
15
16unsigned int
18{
20 ast_node_t node;
21 token_t* current_token;
22 ast_node_t* child;
23 unsigned int ntokens = 0;
24
26 return parse_bitfield_spec(module, parent, token);
27 }
28
30
31 for (;;) {
32 current_token = &token[ntokens];
33
34 switch (current_token->type) {
35 case TK_OPEN_PARENS:
36 child = stack_push(&stack, NT_EXPRESSION, current_token);
37 ntokens += 1 + parse_expression(module, child, current_token + 1);
38
39 if (token[ntokens].type != TK_CLOSE_PARENS) {
41 module,
42 child->token->line,
43 child->token->column,
44 child->token->lexeme.length,
45 "Open parentheses starting here has not a expected close parentheses matching it."
46 );
47
48 return ntokens;
49 }
50
51 ntokens++;
52 break;
53 case TK_IDENTIFIER:
54 case TK_NUMBER:
55 stack_push(&stack, NT_EXPRESSION, current_token);
56 ntokens++;
57 break;
58 case TK_OPERATOR:
59 ntokens += _parse_operator(module, parent, &stack, current_token);
60 break;
61 case TK_EQUAL:
62 ntokens += _parse_binary_operator(module, parent, &stack, current_token);
63 break;
64 case TK_SEMICOLON:
65 case TK_CLOSE_PARENS:
66 case TK_CLOSE_BRACES:
68 case TK_COMMA:
69 case TK_EOF:
70 goto finish_expression;
71 default:
73 module,
74 current_token->line,
75 current_token->column,
76 current_token->lexeme.length,
77 "Unexpected token inside an expression."
78 );
79
80 ntokens++;
81 goto finish_expression;
82 }
83 }
84
85
86finish_expression:
87 // We expect to only have one expression on stack at end. It's the root node of the expression.
88
89 if (stack_isempty(&stack)) {
90 module_add_error(module, token->line, token->column, token->lexeme.length, "Malformed expression starting here.");
92 return ntokens;
93 }
94
95 stack_pop(&stack, &node);
96
97 if (! stack_isempty(&stack)) {
98 stack_pop(&stack, &node);
99
101 module,
102 node.token->line,
103 node.token->column,
104 node.token->lexeme.length,
105 "Unexpected expression starting here."
106 );
107
109 return ntokens;
110 }
111
112 ast_insert_children(parent, &node);
114 return ntokens;
115}
116
117static unsigned int
118_parse_operator(module_t* module, ast_node_t* parent, stack_t* stack, token_t* token)
119{
120 switch (token->value) {
121 case OP_NOT:
122 return _parse_unary_operator(module, parent, stack, token);
123 case OP_MINUS:
124 if (stack_isempty(stack)) {
125 return _parse_unary_operator(module, parent, stack, token);
126 }
127 case OP_AND:
128 case OP_DIV:
129 case OP_MULT:
130 case OP_OR:
131 case OP_PLUS:
132 case OP_SHIFT_LEFT:
133 case OP_SHIFT_RIGHT:
134 case OP_XOR:
135 return _parse_binary_operator(module, parent, stack, token);
136 default:
138 module,
139 token->line,
140 token->column,
142 "Unrecognized operator here. It's really a valid expression operator?"
143 );
144
145 return 1;
146 }
147}
148
149static unsigned int
150_parse_binary_operator(module_t* module, ast_node_t* parent, stack_t* stack, token_t* token)
151{
152 ast_node_t value1;
153
154 if (stack_pop(stack, &value1) != ERR_OK) {
156 module,
157 token->line,
158 token->column,
160 "Binary operator expects a valid value before it, like in: `value OPERATOR value`."
161 );
162
163 return 1;
164 };
165
167 ast_insert_children(op, &value1);
168
169 return 1 + parse_expression(module, op, token + 1);
170}
171
172static unsigned int
173_parse_unary_operator(module_t* module, ast_node_t* parent, stack_t* stack, token_t* token)
174{
176
177 return 1 + parse_expression(module, op, token + 1);
178}
ast_node_t * ast_insert_children(ast_node_t *parent, ast_node_t *child)
Insert a exitent AST node as children of the given parent node.
Definition ast.c:51
@ ERR_OK
Definition err.h:15
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:97
@ OP_SHIFT_LEFT
Definition operators.h:12
@ OP_NOT
Definition operators.h:9
@ OP_SHIFT_RIGHT
Definition operators.h:13
@ OP_PLUS
Definition operators.h:11
@ OP_DIV
Definition operators.h:6
@ OP_XOR
Definition operators.h:14
@ OP_MULT
Definition operators.h:8
@ OP_AND
Definition operators.h:5
@ OP_MINUS
Definition operators.h:7
@ OP_OR
Definition operators.h:10
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.
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 }...
void stack_init(stack_t *stack)
Initializes the given stack.
Definition stack.c:11
ast_node_t * stack_push(stack_t *stack, node_type_t type, token_t *token)
Push a new value on the stack.
Definition stack.c:27
void stack_close(stack_t *stack)
Closes the given stack.
Definition stack.c:20
error_code_t stack_pop(stack_t *stack, ast_node_t *value)
Pop a value from the stack.
Definition stack.c:47
bool stack_isempty(stack_t *stack)
Check if the given stack is empty.
Definition stack.c:59
token_t * token
Definition ast.h:30
unsigned int length
The length of the string.
Definition dstring.h:13
Struct that represents a Mya module.
Definition module.h:34
A struct representing a dynamic stack.
Definition stack.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
struct ast_node ast_node_t
@ NT_EXPRESSION
Definition ast.h:14
struct module module_t
Struct that represents a Mya module.
struct stack stack_t
A struct representing a dynamic stack.
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