libmya 0.1.0
Library to parse Mya language.
Loading...
Searching...
No Matches
parse_statement_inst.c
Go to the documentation of this file.
1#include "ast.h"
2#include "macro_utils.h"
3#include "module.h"
4#include "parser.h"
5#include "types/keywords.h"
6
7static unsigned int
8_parse_inst_args(module_t* module, ast_node_t* parent, token_t* token);
9
10static unsigned int
11_parse_arg_spec(module_t* module, ast_node_t* parent, token_t* token);
12
13unsigned int
15{
16 ast_node_t* node_statement = ast_add_children(parent, NT_STATEMENT, token);
17 token_t* tkid = token + 1;
18
19 if (tkid->type != TK_IDENTIFIER) {
21 module,
22 tkid->line,
23 tkid->column,
24 tkid->lexeme.length,
25 "Expected an identifier here. Example: inst mov[16](arg1: register[32], arg2: immediate[8]) { ... }"
26 );
27
28 return 1;
29 }
30
31 ast_add_children(node_statement, NT_IDENTIFIER, tkid);
32 unsigned int ntokens =
33 2 +
34 parse_size_spec(module, node_statement, token + 2, "inst mov[16](arg1: register[32], arg2: immediate[8]) { ... }");
35
36 token_t* tkopen_parens = token + ntokens;
37
38 if (tkopen_parens->type != TK_OPEN_PARENS) {
40 module,
41 tkopen_parens->line,
42 tkopen_parens->column,
43 tkopen_parens->lexeme.length,
44 "Expected a list of arguments for the instruction inside parentheses. Example: inst mov[16](arg1: register[32], "
45 "arg2: immediate[8]) { ... }"
46 );
47
48 return ntokens + 1;
49 }
50
51 ntokens += _parse_inst_args(module, node_statement, tkopen_parens);
52
53 token_t* tkopen_braces = token + ntokens;
54 if (tkopen_braces->type != TK_OPEN_BRACES) {
56 module,
57 tkopen_braces->line,
58 tkopen_braces->column,
59 tkopen_braces->lexeme.length,
60 "Expected an open braces at start of the body of the instruction. Example: inst mov[16](arg1: register[32], "
61 "arg2: immediate[8]) { ... }"
62 );
63
64 return ntokens;
65 }
66
67 ntokens += parse_fieldlist_spec(module, node_statement, token + ntokens);
68
69 return ntokens;
70}
71
72unsigned int
73_parse_inst_args(module_t* module, ast_node_t* parent, token_t* token)
74{
75 ast_node_t* node_statement = ast_add_children(parent, NT_ARG_LIST, token);
76 unsigned int ntokens = 1;
77 token_t* current;
78
79 for (;;) {
80 current = &token[ntokens];
81
82 switch (current->type) {
83 case TK_IDENTIFIER:
84 ntokens += _parse_arg_spec(module, node_statement, current);
85
86 if (token[ntokens].type != TK_COMMA && token[ntokens].type != TK_CLOSE_PARENS) {
88 module,
89 token[ntokens].line,
90 token[ntokens].column,
91 token[ntokens].lexeme.length,
92 "Expected a comma after the argument specification. Example: inst mov[16](arg1: register[32], arg2: "
93 "immediate[8]) { ... }"
94 );
95 }
96
97 break;
98 case TK_COMMA:
99 ntokens++;
100 break;
101 case TK_CLOSE_PARENS:
102 ntokens++;
103 goto finish;
104 default:
106 module,
107 current->line,
108 current->column,
109 current->lexeme.length,
110 "Unexpected token here. It should follow the syntax like in example: inst mov[16](arg1: register[32], arg2: "
111 "immediate[8]) { ... }"
112 );
113
114 ntokens += parse_advance(current + 1, ARR_TT(TK_COMMA, TK_OPEN_BRACES, TK_CLOSE_BRACES));
115 goto finish;
116 }
117 }
118
119finish:
120 return ntokens;
121}
122
123unsigned int
124_parse_arg_spec(module_t* module, ast_node_t* parent, token_t* token)
125{
126 token_t* tkid = token;
127 token_t* tkcolon = token + 1;
128 token_t* tkkeyword = token + 2;
129
130 if (tkid->type != TK_IDENTIFIER) {
132 module,
133 tkid->line,
134 tkid->column,
135 tkid->lexeme.length,
136 "Expected an argument identifier here. Example: inst mov[16](arg1: register[32], arg2: immediate[8]) { ... }"
137 );
138
139 return 1;
140 }
141
142 if (tkcolon->type != TK_COLON) {
144 module,
145 tkcolon->line,
146 tkcolon->column,
147 tkcolon->lexeme.length,
148 "Expected an colon after argument identifier. Example: inst mov[16](arg1: register[32], arg2: immediate[8]) { "
149 "... }"
150 );
151
152 return 2;
153 }
154
155 if (tkkeyword->type != TK_KEYWORD || (tkkeyword->value != KEY_REGISTER && tkkeyword->value != KEY_IMMEDIATE)) {
157 module,
158 tkkeyword->line,
159 tkkeyword->column,
160 tkkeyword->lexeme.length,
161 "Expected an argument type keyword here. Example: inst mov[16](arg1: register[32], arg2: immediate[8]) { ... }"
162 );
163
164 return 3;
165 }
166
167 ast_node_t* node_statement = ast_add_children(parent, NT_ARG, token);
168 ast_add_children(node_statement, NT_TYPE, tkkeyword);
169
170 return 3 + parse_size_spec(
171 module,
172 node_statement,
173 tkkeyword + 1,
174 "inst mov[16](arg1: register[32], arg2: immediate[8]) { ... }"
175 );
176}
ast_node_t * ast_add_children(ast_node_t *parent, node_type_t type, token_t *token)
Add a new children for the given AST node.
Definition ast.c:40
@ KEY_IMMEDIATE
Definition keywords.h:6
@ KEY_REGISTER
Definition keywords.h:9
#define ARR_TT(...)
Same as ARR_ARG() macro, but with the specific type token_type_t.
Definition macro_utils.h:17
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
unsigned int parse_statement_inst(module_t *module, ast_node_t *parent, token_t *token)
Parse a inst statement adding it as a children on parent AST node.
unsigned int parse_advance(token_t *token, token_type_t *types, size_t ntypes)
Finds the next token TK_EOF or any of the specified types and then returns the number of tokens trave...
unsigned int parse_size_spec(module_t *module, ast_node_t *parent, token_t *token, const char *example)
Parse a size specification in the format [ EXPRESSION ] adding it as a children on parent AST node.
Definition parse_common.c:7
unsigned int parse_fieldlist_spec(module_t *module, ast_node_t *parent, token_t *token)
Parse a field list specification in the format field = EXPRESSION, ... adding it as a children on par...
unsigned int length
The length of the string.
Definition dstring.h:13
Struct that represents a Mya module.
Definition module.h:34
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_ARG
Definition ast.h:11
@ NT_TYPE
Definition ast.h:23
@ NT_IDENTIFIER
Definition ast.h:17
@ NT_STATEMENT
Definition ast.h:21
@ NT_ARG_LIST
Definition ast.h:10
struct module module_t
Struct that represents a Mya module.
struct token token_t
Struct for a Mya token.
@ TK_IDENTIFIER
Definition token.h:19
@ TK_COLON
Definition token.h:15
@ 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_KEYWORD
Definition token.h:20
@ TK_CLOSE_BRACES
Definition token.h:12