topazc
parser.cpp
Go to the documentation of this file.
1
6
9
10std::vector<AST::StmtPtr> Parser::parse() {
11 std::vector<AST::StmtPtr> stmts;
12
13 while (pos < tokens_count) {
14 stmts.push_back(parse_stmt());
15 }
16
17 return stmts;
18}
19
21 pos = 0;
22}
23
25
27 AST::StmtPtr stmt = nullptr;
29 if (match(TOK_PUB)) {
31 }
32 else if (match(TOK_PRIV)) {
34 }
35
36 if (match(TOK_LET)) {
37 stmt = parse_var_decl_stmt();
38 if (!from_for) {
40 }
41 }
42 else if (match(TOK_ID)) {
43 if (match(TOK_OP_LPAREN)) {
44 stmt = parse_func_call_stmt();
45 if (!from_for) {
47 }
48 return stmt;
49 }
50 stmt = parse_var_asgn_stmt();
51 if (!from_for) {
53 }
54 }
55 else if (match(TOK_OP_MULT)) {
56 stmt = parse_var_asgn_stmt();
57 if (!from_for) {
59 }
60 }
61 else if (match(TOK_FUN)) {
62 stmt = parse_func_decl_stmt();
63 }
64 else if (match(TOK_RETURN)) {
65 stmt = parse_return_stmt();
66 if (!from_for) {
68 }
69 }
70 else if (match(TOK_IF)) {
71 stmt = parse_if_else_stmt();
72 }
73 else if (match(TOK_WHILE)) {
75 }
76 else if (match(TOK_DO)) {
78 if (!from_for) {
80 }
81 }
82 else if (match(TOK_FOR)) {
83 stmt = parse_for_cycle_stmt();
84 }
85 else if (match(TOK_BREAK)) {
86 stmt = parse_break_stmt();
87 if (!from_for) {
89 }
90 }
91 else if (match(TOK_CONTINUE)) {
92 stmt = parse_continue_stmt();
93 if (!from_for) {
95 }
96 }
97 else if (match(TOK_MODULE)) {
98 stmt = parse_module_stmt();
99 }
100 else if (match(TOK_USE)) {
101 stmt = parse_use_module_stmt();
102 if (!from_for) {
104 }
105 }
106 else if (match(TOK_EXTERN)) {
107 stmt = parse_extern_stmt();
108 }
109 else {
110 std::stringstream ss;
111 ss << "Expected statement but got \033[0m'" << peek().value << "'\033[31m. Please check statement to mistakes";
112 throw_exception(SUB_PARSER, ss.str(), peek().line, peek().file_name, is_debug);
113 }
114 return stmt;
115}
116
118 Token first_token = peek(-1);
120 AST::Type type = consume_type();
121 std::stringstream ss;
122 ss << "Expected variable name. Token \033[0m'" << peek().value << "'\033[31m is keyword or operator. Please replase it with unique identifier";
123 std::string name = consume(TOK_ID, ss.str(), peek().line).value;
124 AST::ExprPtr expr = nullptr;
125 if (match(TOK_OP_EQ)) {
126 expr = parse_expr();
127 }
128 return std::make_unique<AST::VarDeclStmt>(access, type, std::move(expr), name, first_token.line);
129}
130
132 Token var_token = peek(-1);
133 bool is_deref = false;
134 if (peek(-1).type == TOK_OP_MULT) {
135 var_token = peek();
136 is_deref = true;
137 pos++;
138 }
139 AST::ExprPtr expr = nullptr;
140 if (match(TOK_OP_EQ)) {
141 expr = parse_expr();
142 }
143 else if (is_compound_asgn_operator(peek())) {
144 expr = create_compound_asgn_operator(var_token.value);
145 }
146 else {
147 expr = create_inc_dec_operator(var_token.value);
148 }
149 return std::make_unique<AST::VarAsgnStmt>(var_token.value, std::move(expr), is_deref, var_token.line);
150}
151
153 Token first_token = peek(-1);
155 std::stringstream ss;
156 ss << "Expected function name. Token \033[0m'" << peek().value << "'\033[31m is keyword or operator. Please replase it with unique identifier";
157 std::string name = consume(TOK_ID, ss.str(), peek().line).value;
158 std::vector<AST::Argument> args;
159 if (match(TOK_OP_LPAREN)) {
160 while (!match(TOK_OP_RPAREN)) {
161 args.push_back(parse_argument());
162 if (peek().type != TOK_OP_RPAREN) {
163 ss.str("");
164 ss << "Expected \033[0m','\033[31m between function arguments.\nPlease replace \033[0m'";
165 ss << args[args.size() - 1].name << ": " << args[args.size() - 1].type.to_str() << " " << peek().value << "'\033[31m with: \033[0m'"
166 << args[args.size() - 1].name << ": " << args[args.size() - 1].type.to_str() << ", " << peek().value << "'";
167 consume(TOK_OP_COMMA, ss.str(), peek().line);
168 }
169 }
170 }
171
172 AST::Type ret_type = AST::Type(AST::TYPE_NOTH, "noth");
173 if (match(TOK_OP_NEXT)) {
174 ret_type = consume_type();
175 }
176
177 std::vector<AST::StmtPtr> block;
178 consume(TOK_OP_LBRACE, "Expected \033[0m'{'\033[31m after funtion arguments. Prototypes of functions is unsupported in current Topaz compiler version", peek().line);
179 while (!match(TOK_OP_RBRACE)) {
180 block.push_back(parse_stmt());
181 }
182 return std::make_unique<AST::FuncDeclStmt>(access, name, std::move(args), ret_type, std::move(block), first_token.line);
183}
184
186 Token name_token = peek(-2);
187 std::vector<AST::ExprPtr> args;
188 while (!match(TOK_OP_RPAREN)) {
189 args.push_back(parse_expr());
190 if (peek().type != TOK_OP_RPAREN) {
191 std::stringstream ss;
192 ss << "Expected \033[0m','\033[31m between function arguments.\nPlease replace \033[0m'";
193 ss << peek(-1).value << " " << peek().value << "'\033[31m with: \033[0m'"
194 << peek(-1).value << ", " << peek().value << "'";
195 consume(TOK_OP_COMMA, ss.str(), peek().line);
196 }
197 }
198 return std::make_unique<AST::FuncCallStmt>(name_token.value, std::move(args), name_token.line);
199}
200
202 std::stringstream ss;
203 ss << "Expected function argument name. Token \033[0m'" << peek().value << "'\033[31m is keyword or operator. Please replase it with unique identifier";
204 std::string name = consume(TOK_ID, ss.str(), peek().line).value;
205
206 ss.str("");
207 ss << "Expected \033[0m':'\033[31m between function argument name and type.\nPlease replace \033[0m'";
208 ss << name << "'\033[31m with: \033[0m'" << name << ": '";
209 consume(TOK_OP_COLON, ss.str(), peek().line);
210
211 AST::Type type = consume_type();
212 return AST::Argument(name, type);
213}
214
216 Token first_token = peek(-1);
217 AST::ExprPtr ret_expr = nullptr;
218 if (peek().type != TOK_OP_SEMICOLON) {
219 ret_expr = parse_expr();
220 }
221 return std::make_unique<AST::ReturnStmt>(std::move(ret_expr), first_token.line);
222}
223
225 Token first_token = peek(-1);
226 AST::ExprPtr cond = parse_expr();
227 std::vector<AST::StmtPtr> then_block;
228 consume(TOK_OP_LBRACE, "Expected \033[0m'{'\033[31m after condition", peek().line);
229 while (!match(TOK_OP_RBRACE)) {
230 then_block.push_back(parse_stmt());
231 }
232 std::vector<AST::StmtPtr> else_block;
233 if (match(TOK_ELSE)) {
234 if (match(TOK_OP_LBRACE)) {
235 while (!match(TOK_OP_RBRACE)) {
236 else_block.push_back(parse_stmt());
237 }
238 }
239 else {
240 else_block.push_back(parse_stmt());
241 }
242 }
243 return std::make_unique<AST::IfElseStmt>(std::move(cond), std::move(then_block), std::move(else_block), first_token.line);
244}
245
247 Token first_token = peek(-1);
248 AST::ExprPtr cond = parse_expr();
249 std::vector<AST::StmtPtr> block;
250 consume(TOK_OP_LBRACE, "Expected \033[0m'{'\033[31m after condition", peek().line);
251 while (!match(TOK_OP_RBRACE)) {
252 block.push_back(parse_stmt());
253 }
254 return std::make_unique<AST::WhileCycleStmt>(std::move(cond), std::move(block), first_token.line);
255}
256
258 Token first_token = peek(-1);
259 std::vector<AST::StmtPtr> block;
260 consume(TOK_OP_LBRACE, "Expected \033[0m'{'\033[31m after condition", peek().line);
261 while (!match(TOK_OP_RBRACE)) {
262 block.push_back(parse_stmt());
263 }
264 consume(TOK_WHILE, "Expected \033[0m'while'\033[31m after block in the do-while cycle", peek().line);
265 AST::ExprPtr cond = parse_expr();
266 return std::make_unique<AST::DoWhileCycleStmt>(std::move(cond), std::move(block), first_token.line);
267}
268
270 Token first_token = peek(-1);
271 AST::StmtPtr indexator = parse_stmt(true);
272 consume(TOK_OP_COMMA, "Expected \033[0m','\033[31m after indexator declaration", peek().line);
273 AST::ExprPtr cond = parse_expr();
274 consume(TOK_OP_COMMA, "Expected \033[0m','\033[31m after expression", peek().line);
275 AST::StmtPtr iteration = parse_stmt(true);
276 std::vector<AST::StmtPtr> block;
277 consume(TOK_OP_LBRACE, "Expected \033[0m'{'\033[31m", peek().line);
278 while (!match(TOK_OP_RBRACE)) {
279 block.push_back(parse_stmt());
280 }
281
282 return std::make_unique<AST::ForCycleStmt>(std::move(indexator), std::move(cond), std::move(iteration), std::move(block), first_token.line);
283}
284
286 Token first_token = peek(-1);
287 return std::make_unique<AST::BreakStmt>(first_token.line);
288}
289
291 Token first_token = peek(-1);
292 return std::make_unique<AST::ContinueStmt>(first_token.line);
293}
294
296 Token first_token = peek(-1);
298 std::stringstream ss;
299 ss << "Expected module name. Token \033[0m'" << peek().value << "'\033[31m is keyword or operator. Please replase it with unique identifier";
300 std::string name = consume(TOK_ID, ss.str(), peek().line).value;
301 std::vector<AST::StmtPtr> block;
302 consume(TOK_OP_LBRACE, "Expected \033[0m'{'\033[31m", peek().line);
303 while (!match(TOK_OP_RBRACE)) {
304 block.push_back(parse_stmt());
305 }
306 return std::make_unique<AST::ModuleStmt>(access, first_token.file_name, name, std::move(block), first_token.line);
307}
308
310 Token first_token = peek(-1);
311 std::vector<std::string> path;
312 do {
313 std::stringstream ss;
314 ss << "Expected module name. Token \033[0m'" << peek().value << "'\033[31m is keyword or operator. Please replase it with unique identifier";
315 path.push_back(consume(TOK_ID, ss.str(), peek().line).value);
316 } while (match(TOK_OP_DOT));
317 return std::make_unique<AST::UseModuleStmt>(std::move(path), first_token.line);
318}
319
321 Token first_token = peek();
322 std::stringstream ss;
323 ss << "Expected function name. Token \033[0m'" << peek().value << "'\033[31m is keyword or operator. Please replase it with unique identifier";
324 std::string name = consume(TOK_ID, ss.str(), peek().line).value;
325 std::vector<AST::Argument> args;
326 if (match(TOK_OP_LPAREN)) {
327 while (!match(TOK_OP_RPAREN)) {
328 args.push_back(parse_argument());
329 if (peek().type != TOK_OP_RPAREN) {
330 ss.str("");
331 ss << "Expected \033[0m','\033[31m between function arguments.\nPlease replace \033[0m'";
332 ss << args[args.size() - 1].name << ": " << args[args.size() - 1].type.to_str() << " " << peek().value << "'\033[31m with: \033[0m'"
333 << args[args.size() - 1].name << ": " << args[args.size() - 1].type.to_str() << ", " << peek().value << "'";
334 consume(TOK_OP_COMMA, ss.str(), peek().line);
335 }
336 }
337 }
338
339 AST::Type ret_type = AST::Type(AST::TYPE_NOTH, "noth");
340 if (match(TOK_OP_NEXT)) {
341 ret_type = consume_type();
342 }
344 return std::make_unique<AST::FuncDeclStmt>(AST::ACCESS_NONE, name, std::move(args), ret_type, std::vector<AST::StmtPtr>{}, first_token.line);
345}
346
348 Token first_token = peek(-1);
349 std::string lang_name_lit = consume(TOK_STRING_LIT, "Expected string literal (language name)", peek().line).value;
350 std::vector<AST::StmtPtr> block;
351 consume(TOK_OP_LBRACE, "Expected \033[0m'{'\033[31m", peek().line);
352 while (!match(TOK_OP_RBRACE)) {
353 block.push_back(parse_func_decl_proto_stmt());
354 }
355 return std::make_unique<AST::ExternStmt>(lang_name_lit, std::move(block), first_token.line);
356}
357
361
364 while (match(TOK_OP_L_AND)) {
365 Token token = peek(-1);
366 expr = std::make_unique<AST::BinaryExpr>(token, std::move(expr), parse_l_or_expr(), token.line);
367 }
368 return expr;
369}
370
373 while (match(TOK_OP_L_OR)) {
374 Token token = peek(-1);
375 expr = std::make_unique<AST::BinaryExpr>(token, std::move(expr), parse_equality_expr(), token.line);
376 }
377 return expr;
378}
379
382 while (1) {
383 Token token = peek();
384 if (match(TOK_OP_EQ_EQ)) {
385 expr = std::make_unique<AST::BinaryExpr>(token, std::move(expr), parse_comparation_expr(), token.line);
386 }
387 else if (match(TOK_OP_NOT_EQ_EQ)) {
388 expr = std::make_unique<AST::BinaryExpr>(token, std::move(expr), parse_comparation_expr(), token.line);
389 }
390 else {
391 break;
392 }
393 }
394 return expr;
395}
396
399 while (1) {
400 Token token = peek();
401 if (match(TOK_OP_GT)) {
402 expr = std::make_unique<AST::BinaryExpr>(token, std::move(expr), parse_additive_expr(), token.line);
403 }
404 else if (match(TOK_OP_GT_EQ)) {
405 expr = std::make_unique<AST::BinaryExpr>(token, std::move(expr), parse_additive_expr(), token.line);
406 }
407 else if (match(TOK_OP_LS)) {
408 expr = std::make_unique<AST::BinaryExpr>(token, std::move(expr), parse_additive_expr(), token.line);
409 }
410 else if (match(TOK_OP_LS_EQ)) {
411 expr = std::make_unique<AST::BinaryExpr>(token, std::move(expr), parse_additive_expr(), token.line);
412 }
413 else {
414 break;
415 }
416 }
417 return expr;
418}
419
422 while (1) {
423 Token token = peek();
424 if (match(TOK_OP_PLUS)) {
425 expr = std::make_unique<AST::BinaryExpr>(token, std::move(expr), parse_multiplicative_expr(), token.line);
426 }
427 else if (match(TOK_OP_MINUS)) {
428 expr = std::make_unique<AST::BinaryExpr>(token, std::move(expr), parse_multiplicative_expr(), token.line);
429 }
430 else {
431 break;
432 }
433 }
434 return expr;
435}
436
439 while (1) {
440 Token token = peek();
441 if (match(TOK_OP_MULT)) {
442 expr = std::make_unique<AST::BinaryExpr>(token, std::move(expr), parse_unary_expr(), token.line);
443 }
444 else if (match(TOK_OP_DIV)) {
445 expr = std::make_unique<AST::BinaryExpr>(token, std::move(expr), parse_unary_expr(), token.line);
446 }
447 else if (match(TOK_OP_MODULO)) {
448 expr = std::make_unique<AST::BinaryExpr>(token, std::move(expr), parse_unary_expr(), token.line);
449 }
450 else {
451 break;
452 }
453 }
454 return expr;
455}
456
458 Token token = peek();
459 while (1) {
460 if (match(TOK_OP_MINUS)) {
461 return std::make_unique<AST::UnaryExpr>(token, parse_primary_expr(), token.line);
462 }
463 else if (match(TOK_OP_L_NOT)) {
464 return std::make_unique<AST::UnaryExpr>(token, parse_primary_expr(), token.line);
465 }
466 else if (match(TOK_OP_MULT)) {
467 return std::make_unique<AST::UnaryExpr>(token, parse_unary_expr(), token.line);
468 }
469 else if (match(TOK_OP_REF)) {
470 return std::make_unique<AST::UnaryExpr>(token, parse_unary_expr(), token.line);
471 }
472 else {
473 break;
474 }
475 }
476 return parse_primary_expr();
477}
478
480 Token token = peek();
481 switch (token.type) {
482 case TOK_OP_LPAREN: {
483 pos++;
484 AST::ExprPtr expr = parse_expr();
485 consume(TOK_OP_RPAREN, "Expected ')'. You forgot to specify the closing ')'", token.line);
486 return expr;
487 }
488 case TOK_ID:
489 pos++;
490 if (match(TOK_OP_LPAREN)) {
491 std::vector<AST::ExprPtr> args;
492 uint32_t c_pos = pos;
493 while (!match(TOK_OP_RPAREN)) {
494 args.push_back(parse_expr());
495 if (peek().type != TOK_OP_RPAREN) {
496 std::stringstream ss;
497 ss << "Expected \033[0m','\033[31m between function arguments.\nPlease replace \033[0m'";
498 ss << peek(-1).value << " " << peek().value << "'\033[31m with: \033[0m'"
499 << peek(-1).value << ", " << peek().value << "'";
500 consume(TOK_OP_COMMA, ss.str(), peek().line);
501 }
502 }
503 if (match(TOK_OP_DOT)) {
504 pos = c_pos - 2; // return to the identifier
505 return parse_obj_chain_expr();
506 }
507 return std::make_unique<AST::FuncCallExpr>(token.value, std::move(args), token.line);
508 }
509 else if (peek().type == TOK_OP_INC || peek().type == TOK_OP_DEC) {
510 return create_inc_dec_operator(token.value);
511 }
512 else if (match(TOK_OP_DOT)) {
513 pos -= 2; // return to the identifier
514 return parse_obj_chain_expr();
515 }
516 return std::make_unique<AST::VarExpr>(token.value, token.line);
518 pos++;
519 return std::make_unique<AST::CharacterLiteral>(token.value[0], token.line);
520 case TOK_SHORT_LIT:
521 pos++;
522 return std::make_unique<AST::ShortLiteral>(std::stoll(token.value), token.line);
523 case TOK_INT_LIT:
524 pos++;
525 return std::make_unique<AST::IntLiteral>(std::stoll(token.value), token.line);
526 case TOK_LONG_LIT:
527 pos++;
528 return std::make_unique<AST::LongLiteral>(std::stoll(token.value), token.line);
529 case TOK_FLOAT_LIT:
530 pos++;
531 return std::make_unique<AST::FloatLiteral>(std::stold(token.value), token.line);
532 case TOK_DOUBLE_LIT:
533 pos++;
534 return std::make_unique<AST::DoubleLiteral>(std::stold(token.value), token.line);
535 case TOK_BOOLEAN_LIT:
536 pos++;
537 return std::make_unique<AST::BoolLiteral>(token.value == "true", token.line);
538 case TOK_STRING_LIT:
539 pos++;
540 return std::make_unique<AST::StringLiteral>(token.value, token.line);
541 default:
542 std::stringstream ss;
543 ss << "Expected expression, but got \033[0m'" << peek().value << "'\033[31m. Please check expression to mistakes";
544 throw_exception(SUB_PARSER, ss.str(), token.line, token.file_name, is_debug);
545 }
546}
547
549 Token first_token = peek();
550 std::vector<AST::ExprPtr> chain;
551 do {
552 std::stringstream ss;
553 ss << "Expected object name. Token \033[0m'" << peek().value << "'\033[31m is keyword or operator. Please replase it with unique identifier";
554 Token token = consume(TOK_ID, ss.str(), peek().line);
555 if (match(TOK_OP_LPAREN)) {
556 std::vector<AST::ExprPtr> args;
557 while (!match(TOK_OP_RPAREN)) {
558 args.push_back(parse_expr());
559 if (peek().type != TOK_OP_RPAREN) {
560 std::stringstream ss;
561 ss << "Expected \033[0m','\033[31m between function arguments.\nPlease replace \033[0m'";
562 ss << peek(-1).value << " " << peek().value << "'\033[31m with: \033[0m'"
563 << peek(-1).value << ", " << peek().value << "'";
564 consume(TOK_OP_COMMA, ss.str(), peek().line);
565 }
566 }
567 chain.push_back(std::make_unique<AST::FuncCallExpr>(token.value, std::move(args), token.line));
568 }
569 else {
570 chain.push_back(std::make_unique<AST::VarExpr>(token.value, token.line));
571 }
572 } while (match(TOK_OP_DOT));
573 return std::make_unique<AST::ChainObjects>(std::move(chain), first_token.line);
574}
575
576Token Parser::peek(int32_t rpos) const {
577 if (pos + rpos >= tokens_count || pos + rpos < 0) {
578 std::stringstream ss;
579 ss << "Index out of range: " << pos + rpos << '/' << tokens_count;
580 throw_exception(SUB_PARSER, ss.str(), peek().line, peek().file_name, is_debug);
581 }
582 return tokens[pos + rpos];
583}
584
586 if (peek().type == type) {
587 pos++;
588 return true;
589 }
590 return false;
591}
592
593Token Parser::consume(TokenType type, std::string err_msg, uint32_t line) {
594 Token token = peek();
595 if (match(type)) {
596 return token;
597 }
598 throw_exception(SUB_PARSER, err_msg, line, token.file_name, is_debug);
599}
600
602 Token token = peek();
603 bool is_const = false;
604 bool is_ptr = false;
605 bool is_nullable = false;
606 if (match(TOK_CONST)) {
607 is_const = true;
608 }
609 switch (peek().type) {
610 case TOK_BOOL:
611 case TOK_CHAR:
612 case TOK_SHORT:
613 case TOK_INT:
614 case TOK_LONG:
615 case TOK_FLOAT:
616 case TOK_DOUBLE:
617 case TOK_NOTH: {
618 Token type = peek();
619 pos++;
620 if (match(TOK_OP_MULT)) {
621 is_ptr = true;
622 }
623 if (match(TOK_OP_QUESTION)) {
624 is_nullable = true;
625 }
626 return AST::Type(ttype_to_tvalue(type.type), type.value, is_const, is_ptr, is_nullable);
627 }
628 default: {
629 std::stringstream ss;
630 ss << "Token \033[0m'" << peek().value << "'\033[31m is not type. Please replase it to exists type";
631 throw_exception(SUB_PARSER, ss.str(), peek().line, peek().file_name, is_debug);
632 }
633 }
634}
635
637 std::stringstream ss;
638 ss << "Expected \033[0m';'\033[31m in the end of variable definition. ";
639 if (pos == tokens_count) {
640 ss << "Please add \033[0m';'\033[31m into the end of variable definition";
641 }
642 else {
643 ss << "Please replace \033[0m'" << peek().value << "'\033[31m with \033[0m';'";
644 }
645 consume(TOK_OP_SEMICOLON, ss.str(), peek().line);
646}
647
649 switch (type) {
650 case TOK_BOOL:
651 return AST::TYPE_BOOL;
652 case TOK_CHAR:
653 return AST::TYPE_CHAR;
654 case TOK_SHORT:
655 return AST::TYPE_SHORT;
656 case TOK_INT:
657 return AST::TYPE_INT;
658 case TOK_LONG:
659 return AST::TYPE_LONG;
660 case TOK_FLOAT:
661 return AST::TYPE_FLOAT;
662 case TOK_DOUBLE:
663 return AST::TYPE_DOUBLE;
664 case TOK_NOTH:
665 return AST::TYPE_NOTH;
666 default:
667 std::stringstream ss;
668 ss << "Token \033[0m'" << peek().value << "'\033[31m is not type. Please replase it to exists types";
669 throw_exception(SUB_PARSER, ss.str(), peek().line, peek().file_name, is_debug);
670 }
671}
672
674 switch (token.type) {
675 case TOK_OP_PLUS_EQ:
676 case TOK_OP_MINUS_EQ:
677 case TOK_OP_MULT_EQ:
678 case TOK_OP_DIV_EQ:
679 case TOK_OP_MODULO_EQ:
680 return true;
681 default:
682 return false;
683 }
684}
685
687 Token token = peek();
688 pos++;
689 switch (token.type) {
690 case TOK_OP_PLUS_EQ:
691 return std::make_unique<AST::BinaryExpr>(Token(TOK_OP_PLUS, "+", token.line, token.column, token.file_name), std::make_unique<AST::VarExpr>(var_name, token.line), parse_expr(), token.line);
692 case TOK_OP_MINUS_EQ:
693 return std::make_unique<AST::BinaryExpr>(Token(TOK_OP_MINUS, "-", token.line, token.column, token.file_name), std::make_unique<AST::VarExpr>(var_name, token.line), parse_expr(), token.line);
694 case TOK_OP_MULT_EQ:
695 return std::make_unique<AST::BinaryExpr>(Token(TOK_OP_MULT, "*", token.line, token.column, token.file_name), std::make_unique<AST::VarExpr>(var_name, token.line), parse_expr(), token.line);
696 case TOK_OP_DIV_EQ:
697 return std::make_unique<AST::BinaryExpr>(Token(TOK_OP_DIV, "/", token.line, token.column, token.file_name), std::make_unique<AST::VarExpr>(var_name, token.line), parse_expr(), token.line);
698 case TOK_OP_MODULO_EQ:
699 return std::make_unique<AST::BinaryExpr>(Token(TOK_OP_MODULO, "%", token.line, token.column, token.file_name), std::make_unique<AST::VarExpr>(var_name, token.line), parse_expr(), token.line);
700 default: {
701 std::stringstream ss;
702 ss << "Unsupported compound assignment operator: \033[0m'" << token.value << "'\033[31m. Please check your Topaz compiler version and fix the problematic section of the code";
703 throw_exception(SUB_PARSER, ss.str(), token.line, peek().file_name, is_debug);
704 }
705 }
706}
707
709 Token token = peek();
710 pos++;
711 switch (token.type) {
712 case TOK_OP_INC:
713 return std::make_unique<AST::BinaryExpr>(Token(TOK_OP_PLUS, "+", token.line, token.column, token.file_name), std::make_unique<AST::VarExpr>(var_name, token.line), std::make_unique<AST::IntLiteral>(1, token.line), token.line);
714 case TOK_OP_DEC:
715 return std::make_unique<AST::BinaryExpr>(Token(TOK_OP_MINUS, "-", token.line, token.column, token.file_name), std::make_unique<AST::VarExpr>(var_name, token.line), std::make_unique<AST::IntLiteral>(1, token.line), token.line);
716 default: {
717 std::stringstream ss;
718 ss << "Unsupported increment/decrement operator: \033[0m'" << token.value << "'\033[31m. Please check your Topaz compiler version and fix the problematic section of the code";
719 throw_exception(SUB_PARSER, ss.str(), token.line, peek().file_name, is_debug);
720 }
721 }
722}
void consume_semicolon()
Method for skipping semicolon in the end of statement.
Definition parser.cpp:636
AST::ExprPtr parse_unary_expr()
Method for parsing expression as 'unary'.
Definition parser.cpp:457
AST::ExprPtr parse_expr()
Method for parsing expressions.
Definition parser.cpp:358
AST::StmtPtr parse_func_decl_proto_stmt()
Method for parsing of functions prototypes.
Definition parser.cpp:320
AST::StmtPtr parse_while_cycle_stmt()
Method for parsing of while cycle.
Definition parser.cpp:246
AST::ExprPtr parse_l_or_expr()
Method for parsing expression as 'logical or'.
Definition parser.cpp:371
AST::ExprPtr parse_additive_expr()
Method for parsing expression as 'additive'.
Definition parser.cpp:420
AST::StmtPtr parse_func_call_stmt()
Method for parsing of functions calling.
Definition parser.cpp:185
AST::StmtPtr parse_do_while_cycle_stmt()
Method for parsing of do-while cycle.
Definition parser.cpp:257
AST::StmtPtr parse_if_else_stmt()
Method for parsing of control flow operators (aka if-else).
Definition parser.cpp:224
std::vector< Token > tokens
Definition parser.hpp:16
AST::ExprPtr parse_primary_expr()
Method for parsing expression as 'primary'.
Definition parser.cpp:479
AST::StmtPtr parse_return_stmt()
Method for parsing of 'return'.
Definition parser.cpp:215
AST::StmtPtr parse_use_module_stmt()
Method for parsing of import the module.
Definition parser.cpp:309
AST::StmtPtr parse_var_asgn_stmt()
Method for parsing of variable assignment.
Definition parser.cpp:131
AST::Argument parse_argument()
Method for parsing of function argument.
Definition parser.cpp:201
AST::StmtPtr parse_stmt(bool from_for=false)
Method for parsing only one statement.
Definition parser.cpp:26
AST::Type consume_type()
Method for verifyng the Topaz type by current tokens.
Definition parser.cpp:601
std::vector< AST::StmtPtr > parse()
Method for parsing tokens into AST tree.
Definition parser.cpp:10
AST::StmtPtr parse_var_decl_stmt()
Method for parsing of variable declaration.
Definition parser.cpp:117
AST::ExprPtr create_inc_dec_operator(std::string var_name)
Method for creating increment/decrement operator and returns expression of assignment.
Definition parser.cpp:708
uint32_t pos
Definition parser.hpp:18
bool is_compound_asgn_operator(Token token)
Method for checking whether the passed token is a compound assignment operator.
Definition parser.cpp:673
AST::StmtPtr parse_func_decl_stmt()
Method for parsing of functions declaration.
Definition parser.cpp:152
AST::StmtPtr parse_break_stmt()
Method for parsing of break statement.
Definition parser.cpp:285
bool is_debug
Definition parser.hpp:19
AST::ExprPtr parse_equality_expr()
Method for parsing expression as 'equality'.
Definition parser.cpp:380
AST::ExprPtr parse_comparation_expr()
Method for parsing expression as 'comparation'.
Definition parser.cpp:397
AST::StmtPtr parse_continue_stmt()
Method for parsing of continue statement.
Definition parser.cpp:290
AST::StmtPtr parse_extern_stmt()
Method for parsing of declaration functions prototypes as extern.
Definition parser.cpp:347
size_t tokens_count
Definition parser.hpp:17
AST::ExprPtr parse_l_and_expr()
Method for parsing expression as 'logical and'.
Definition parser.cpp:362
AST::StmtPtr parse_for_cycle_stmt()
Method for parsing of for cycle.
Definition parser.cpp:269
Token peek(int32_t rpos=0) const
Method for getting token from tokens by parser pos and passed offset.
Definition parser.cpp:576
AST::ExprPtr create_compound_asgn_operator(std::string var_name)
Method for creating compound assignment operator and returns expression of assignment.
Definition parser.cpp:686
AST::ExprPtr parse_multiplicative_expr()
Method for parsing expression as 'multiplicative'.
Definition parser.cpp:437
Token consume(TokenType type, std::string err_msg, uint32_t line)
Method for verifying the type of the current token.
Definition parser.cpp:593
AST::StmtPtr parse_module_stmt()
Method for parsing of module definition.
Definition parser.cpp:295
AST::TypeValue ttype_to_tvalue(TokenType type)
Method for convert type of token to type of Topaz value.
Definition parser.cpp:648
AST::ExprPtr parse_obj_chain_expr()
Method for parsing expresion as chain of objects.
Definition parser.cpp:548
bool match(TokenType type)
Method for skipping the current token if its type is equal to the passed one.
Definition parser.cpp:585
void reset()
Method for resetting all parameters in parser.
Definition parser.cpp:20
void throw_exception(SubsystemType type, std::string msg, uint32_t line, std::string file_name, bool is_debug)
Function for throwing exception.
Definition exception.cpp:30
Header file for defining thrown exceptions by the compiler.
@ SUB_PARSER
Definition exception.hpp:16
AccessModifier
Access modifier for statements.
Definition ast.hpp:97
@ ACCESS_PRIVATE
Definition ast.hpp:99
@ ACCESS_PUBLIC
Definition ast.hpp:100
@ ACCESS_NONE
Definition ast.hpp:98
std::unique_ptr< Stmt > StmtPtr
Definition ast.hpp:125
TypeValue
Type values enum.
Definition ast.hpp:19
@ TYPE_INT
Definition ast.hpp:23
@ TYPE_CHAR
Definition ast.hpp:21
@ TYPE_FLOAT
Definition ast.hpp:25
@ TYPE_BOOL
Definition ast.hpp:20
@ TYPE_LONG
Definition ast.hpp:24
@ TYPE_DOUBLE
Definition ast.hpp:26
@ TYPE_NOTH
Definition ast.hpp:27
@ TYPE_SHORT
Definition ast.hpp:22
std::unique_ptr< Expr > ExprPtr
Definition ast.hpp:126
AST::AccessModifier current_access
Definition parser.cpp:24
Header file for defining parser.
Structure for describing the argument (in function or method).
Definition ast.hpp:87
Structure for describing the type.
Definition ast.hpp:37
Token structure.
Definition token.hpp:92
std::string value
Definition token.hpp:94
TokenType type
Definition token.hpp:93
uint32_t line
Definition token.hpp:96
std::string file_name
Definition token.hpp:98
uint32_t column
Definition token.hpp:97
TokenType
All tokens types.
Definition token.hpp:14
@ TOK_OP_DEC
Definition token.hpp:57
@ TOK_OP_DIV_EQ
Definition token.hpp:61
@ TOK_OP_COMMA
Definition token.hpp:75
@ TOK_BREAK
Definition token.hpp:32
@ TOK_OP_DIV
Definition token.hpp:60
@ TOK_OP_NEXT
Definition token.hpp:86
@ TOK_OP_EQ_EQ
Definition token.hpp:65
@ TOK_USE
Definition token.hpp:36
@ TOK_LET
Definition token.hpp:24
@ TOK_IF
Definition token.hpp:26
@ TOK_OP_LS
Definition token.hpp:69
@ TOK_OP_GT_EQ
Definition token.hpp:68
@ TOK_CHARACTER_LIT
Definition token.hpp:43
@ TOK_OP_MINUS_EQ
Definition token.hpp:56
@ TOK_OP_LBRACE
Definition token.hpp:81
@ TOK_STRING_LIT
Definition token.hpp:50
@ TOK_PRIV
Definition token.hpp:35
@ TOK_OP_RBRACE
Definition token.hpp:82
@ TOK_SHORT_LIT
Definition token.hpp:44
@ TOK_INT_LIT
Definition token.hpp:45
@ TOK_FOR
Definition token.hpp:28
@ TOK_OP_LPAREN
Definition token.hpp:79
@ TOK_OP_NOT_EQ_EQ
Definition token.hpp:66
@ TOK_OP_PLUS_EQ
Definition token.hpp:53
@ TOK_ID
Definition token.hpp:42
@ TOK_OP_L_OR
Definition token.hpp:73
@ TOK_OP_SEMICOLON
Definition token.hpp:78
@ TOK_BOOL
Definition token.hpp:15
@ TOK_DOUBLE
Definition token.hpp:21
@ TOK_DO
Definition token.hpp:29
@ TOK_OP_MULT_EQ
Definition token.hpp:59
@ TOK_OP_RPAREN
Definition token.hpp:80
@ TOK_MODULE
Definition token.hpp:33
@ TOK_OP_INC
Definition token.hpp:54
@ TOK_OP_QUESTION
Definition token.hpp:85
@ TOK_OP_PLUS
Definition token.hpp:52
@ TOK_WHILE
Definition token.hpp:30
@ TOK_NOTH
Definition token.hpp:22
@ TOK_OP_COLON
Definition token.hpp:77
@ TOK_LONG
Definition token.hpp:19
@ TOK_OP_L_NOT
Definition token.hpp:71
@ TOK_CHAR
Definition token.hpp:16
@ TOK_OP_DOT
Definition token.hpp:76
@ TOK_OP_EQ
Definition token.hpp:64
@ TOK_OP_MODULO_EQ
Definition token.hpp:63
@ TOK_FLOAT_LIT
Definition token.hpp:47
@ TOK_OP_L_AND
Definition token.hpp:72
@ TOK_DOUBLE_LIT
Definition token.hpp:48
@ TOK_OP_MODULO
Definition token.hpp:62
@ TOK_CONST
Definition token.hpp:37
@ TOK_SHORT
Definition token.hpp:17
@ TOK_FUN
Definition token.hpp:25
@ TOK_OP_MULT
Definition token.hpp:58
@ TOK_ELSE
Definition token.hpp:27
@ TOK_OP_REF
Definition token.hpp:74
@ TOK_LONG_LIT
Definition token.hpp:46
@ TOK_FLOAT
Definition token.hpp:20
@ TOK_INT
Definition token.hpp:18
@ TOK_OP_GT
Definition token.hpp:67
@ TOK_OP_MINUS
Definition token.hpp:55
@ TOK_PUB
Definition token.hpp:34
@ TOK_OP_LS_EQ
Definition token.hpp:70
@ TOK_BOOLEAN_LIT
Definition token.hpp:49
@ TOK_EXTERN
Definition token.hpp:40
@ TOK_RETURN
Definition token.hpp:38
@ TOK_CONTINUE
Definition token.hpp:31