libmya 0.1.0
Library to parse Mya language.
Loading...
Searching...
No Matches
mya.h File Reference
#include "module.h"
#include "token.h"
#include "types/mir.h"
Include dependency graph for mya.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

error_code_t mya_lexer (module_t *module)
 Make the lexical analysis on the given module.
 
error_code_t mya_parser (module_t *module)
 Make the syntactical analysis on the given module and construct the AST.
 
error_code_t mya_evaluator (mir_t *mir, module_t *module)
 Make the semantic analysis on the given module and evaluates the statements, constructing the in-memory intermediate representation.
 

Function Documentation

◆ mya_evaluator()

error_code_t mya_evaluator ( mir_t * mir,
module_t * module )

Make the semantic analysis on the given module and evaluates the statements, constructing the in-memory intermediate representation.

Parameters
mirWhere the intermediate representation will be added.
moduleThe module to be evaluated.
Returns
ERR_INVALID_CODE on evaluator found some errors on module.
ERR_OK on finished successful.

Definition at line 6 of file evaluator.c.

7{
8 ast_node_t* current;
9
10 for (int i = 0; i < module->ast.children_count; i++) {
11 current = &module->ast.children[i];
12
13 switch (current->token->value) {
14 case KEY_INCLUDE:
15 eval_include(mir, module, current);
16 break;
17 case KEY_SET:
18 eval_set(mir, module, current);
19 break;
20 case KEY_BITFIELD:
21 eval_bitfield(mir, module, current);
22 break;
23 case KEY_REGISTER:
24 eval_register(mir, module, current);
25 break;
26 case KEY_INST:
27 break;
28 default:
30 module,
31 current->token->line,
32 current->token->column,
33 current->token->lexeme.length,
34 "It's an invalid statement keyword. Are you sure it's a valid command or declaration?"
35 );
36
37 return ERR_INVALID_CODE;
38 }
39 }
40 return ERR_OK;
41}
@ ERR_INVALID_CODE
Definition err.h:18
@ ERR_OK
Definition err.h:15
void eval_bitfield(mir_t *mir, module_t *module, ast_node_t *ast)
Evaluates a bitfield statement.
void eval_include(mir_t *mir, module_t *module, ast_node_t *ast)
Evaluates an include statement.
Definition eval_include.c:8
void eval_register(mir_t *mir, module_t *module, ast_node_t *ast)
Evaluates a register statement.
void eval_set(mir_t *mir, module_t *module, ast_node_t *ast)
Evaluates a set statement.
Definition eval_set.c:8
@ KEY_INST
Definition keywords.h:8
@ KEY_SET
Definition keywords.h:10
@ KEY_BITFIELD
Definition keywords.h:5
@ KEY_REGISTER
Definition keywords.h:9
@ KEY_INCLUDE
Definition keywords.h:7
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
unsigned int children_count
Definition ast.h:32
token_t * token
Definition ast.h:30
unsigned int length
The length of the string.
Definition dstring.h:13
Mya in-memory intermediate representation.
Definition mir.h:117
Struct that represents a Mya module.
Definition module.h:36
ast_node_t ast
AST of the module.
Definition module.h:39
long long int value
Integer value of the token.
Definition token.h:38
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

◆ mya_lexer()

error_code_t mya_lexer ( module_t * module)

Make the lexical analysis on the given module.

It will construct the module->tokens list and maybe registry some errors on module->errors list.

Parameters
moduleThe module for make the lexical analysis.
Returns
ERR_INVALID_CODE on lexer found some errors on module.
ERR_OK on finished successful.

Definition at line 53 of file lexer.c.

54{
55 char message[128];
56 int ch;
57 unsigned int line = 1;
58 unsigned int column = 1;
60
61 for (; module_lookup(module, &ch, 0) == ERR_OK; column++) {
62 if (isblank(ch)) {
63 module_getc(module, &ch);
64 continue;
65 }
66
67 switch (ch) {
68 case '#':
69 _mod_rm_line(module);
70 line++;
71 column = 0;
72 continue;
73 case '\n':
74 line++;
75 column = 0;
76 break;
77 case '{':
79 break;
80 case '}':
82 break;
83 case '(':
85 break;
86 case ')':
88 break;
89 case '[':
91 break;
92 case ']':
94 break;
95 case ';':
97 break;
98 case ':':
99 MOD_ADD(":", TK_COLON);
100 break;
101 case ',':
102 MOD_ADD(",", TK_COMMA);
103 break;
104 case '=':
105 MOD_ADD("=", TK_EQUAL);
106 break;
107 case '"':
108 column += _mod_read_string(module, line, column) - 1;
109 continue;
110 default:
111 if (isdigit(ch)) {
112 column += _mod_read_number(module, line, column) - 1;
113 continue;
114 }
115
116 if (ispunct(ch)) {
117 column += _mod_read_operator(module, line, column) - 1;
118 continue;
119 }
120
121 if (isalnum(ch)) {
122 column += _mod_read_identifier(module, line, column) - 1;
123 continue;
124 }
125
126 sprintf(message, "Character '%c' is unexpected here!\n", ch);
127
128 module_add_error(module, line, column, 1, message);
129 break;
130 }
131
132 module_getc(module, &ch);
133 }
134
135 MOD_ADD(":EOF:", TK_EOF);
136
137 return (module->errors_count == 0) ? ERR_OK : ERR_INVALID_CODE;
138}
#define MOD_ADD(lexeme, type)
Definition lexer.c:47
error_code_t module_lookup(module_t *module, int *chret, unsigned int seek)
Get a character on module's file, without removing it from the queue.
Definition module.c:68
error_code_t module_getc(module_t *module, int *chret)
Get next character on module's file, removing it from the queue.
Definition module.c:60
unsigned int errors_count
Number of errors on errors list.
Definition module.h:44
Struct for a Mya token.
Definition token.h:34
struct token token_t
Struct for a Mya token.
@ TK_OPEN_BRACKET
Definition token.h:23
@ 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_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

◆ mya_parser()

error_code_t mya_parser ( module_t * module)

Make the syntactical analysis on the given module and construct the AST.

Parameters
moduleThe module for make the syntactical analysis.
Returns
ERR_INVALID_CODE on parser found some errors on module.
ERR_OK on finished successful.

Definition at line 12 of file parser.c.

13{
15
16 for (unsigned int tk_index = 0; tk_index < module->tokens_count;) {
17 token = &module->tokens[tk_index];
18
19 switch (token->type) {
20 case TK_KEYWORD:
22 "Parsing statement: %s at %s:%d:%d.\n",
25 token->line,
27 );
28
29 tk_index += parse_statement(module, &module->ast, token);
30 tk_index += parse_advance(&module->tokens[tk_index], ARR_TT(TK_KEYWORD));
31 break;
32 case TK_EOF:
33 goto finish;
34 default:
36 module,
37 token->line,
40 "Unexpected token here. It's expected to be a valid statement keyword."
41 );
42
43 tk_index++;
44 break;
45 }
46 }
47
48finish:
49 return (module->errors_count == 0) ? ERR_OK : ERR_INVALID_CODE;
50}
#define DPRINTF2(fmt,...)
Definition debug.h:23
#define ARR_TT(...)
Same as ARR_ARG() macro, but with the specific type token_type_t.
Definition macro_utils.h:17
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_statement(module_t *module, ast_node_t *parent, token_t *token)
Parse a statement adding it as a children on parent AST node.
char * data
Pointer for the raw string content (a normal C string).
Definition dstring.h:12
char filepath[MODULE_MAX_FILEPATH_SIZE+1]
Module's filepath.
Definition module.h:49
token_t * tokens
List of tokens inside the module.
Definition module.h:38
unsigned int tokens_count
Number of tokens on tokens list.
Definition module.h:42
token_type_t type
Token type.
Definition token.h:35
@ TK_KEYWORD
Definition token.h:20