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

Go to the source code of this file.

Functions

int64_t eval_expression (hashtable_t *variables, module_t *module, ast_node_t *ast)
 Evaluates a mathetical expression.
 
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.
 
void eval_inst (mir_t *mir, module_t *module, ast_node_t *ast)
 Evaluates an inst statement.
 
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.
 
void eval_bitfield_spec (mir_bitfield_spec_t *spec, module_t *module, ast_node_t *ast, hashtable_t *variables)
 Evaluates a bitfield specification expression.
 

Function Documentation

◆ eval_bitfield()

void eval_bitfield ( mir_t * mir,
module_t * module,
ast_node_t * ast )

Evaluates a bitfield statement.

Parameters
mirThe MIR struct where to add the intermediate represetation.
moduleMya module where the statement is in.
astThe AST node where start the statement.

Definition at line 9 of file eval_bitfield.c.

10{
11 if (ast->type != NT_STATEMENT || ast->token->value != KEY_BITFIELD) {
13 module,
14 ast->token->line,
15 ast->token->column,
16 ast->token->lexeme.length,
17 "Unexpected token where is expected a bitfield statement."
18 );
19
20 return;
21 }
22
23 ast_node_t* node_name = &ast->children[0];
24 ast_node_t* node_size = &ast->children[1];
25
26 int64_t size = eval_expression(&mir->variables, module, node_size);
27 if (size < 0 || size > 512) {
29 module,
30 node_size->token->line,
31 node_size->token->column,
32 node_size->token->lexeme.length,
33 "Bitfield size should be between 0 and 512."
34 );
35
36 return;
37 }
38
39 const char* name = node_name->token->lexeme.data;
40 if (! isupper(name[0])) {
42 module,
43 node_name->token->line,
44 node_name->token->column,
45 node_name->token->lexeme.length,
46 "Bitfield name should start with upper case."
47 );
48
49 return;
50 }
51
52 mir_bitfield_t* bitfield = mir_add_bitfield(mir, name, size);
53 if (ast->children_count != 3) {
54 return;
55 }
56
57 ast_node_t* node_body = &ast->children[2];
58 if (node_body->type != NT_BITFIELD_BODY) {
60 module,
61 node_body->token->line,
62 node_body->token->column,
63 node_body->token->lexeme.length,
64 "Bitfield body declaration expected here."
65 );
66
67 return;
68 }
69
70 int64_t total_size = 0;
71
72 for (int i = 0; i < node_body->children_count; i++) {
73 ast_node_t* field = &node_body->children[i];
74 const char* field_name = field->token->lexeme.data;
75 int64_t field_size = eval_expression(&mir->variables, module, field->children);
76
77 mir_bitfield_add_field(bitfield, field_name, field_size);
78
79 total_size += field_size;
80 }
81
82 if (size != total_size) {
84 module,
85 node_size->token->line,
86 node_size->token->column,
87 node_size->token->lexeme.length,
88 "Bitfield size should be equal to the sum of all field sizes."
89 );
90 }
91}
int64_t eval_expression(hashtable_t *variables, module_t *module, ast_node_t *ast)
Evaluates a mathetical expression.
@ KEY_BITFIELD
Definition keywords.h:5
mir_bitfield_field_t * mir_bitfield_add_field(mir_bitfield_t *bitfield, const char *name, uint32_t size)
Add a new field to a bitfield declaration.
Definition mir.c:94
mir_bitfield_t * mir_add_bitfield(mir_t *mir, const char *name, uint32_t size)
Add a new bitfield declaration.
Definition mir.c:58
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
struct ast_node * children
Definition ast.h:31
node_type_t type
Definition ast.h:29
unsigned int length
The length of the string.
Definition dstring.h:13
char * data
Pointer for the raw string content (a normal C string).
Definition dstring.h:12
Mya in-memory intermediate representation.
Definition mir.h:117
hashtable_t variables
Hashtable of variables.
Definition mir.h:121
Struct that represents a Mya module.
Definition module.h:36
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
@ NT_STATEMENT
Definition ast.h:21
@ NT_BITFIELD_BODY
Definition ast.h:12
struct mir_bitfield mir_bitfield_t
A bitfield declaration.

◆ eval_bitfield_spec()

void eval_bitfield_spec ( mir_bitfield_spec_t * spec,
module_t * module,
ast_node_t * ast,
hashtable_t * variables )

Evaluates a bitfield specification expression.

Parameters
specThe spec struct where to save the spec data.
moduleMya module where the expression is in.
astThe AST node where start the bitfield specification.
variablesThe hashtable with the declared variables.

Definition at line 10 of file eval_bitfield_spec.c.

11{
12 if (ast->type != NT_BITFIELD_SPEC) {
14 module,
15 ast->token->line,
16 ast->token->column,
17 ast->token->lexeme.length,
18 "Unexpected token where is expected a bitfield specification expression."
19 );
20
21 return;
22 }
23
24 ast_node_t* field_spec = &ast->children[0];
25 if (field_spec->type != NT_FIELD_SPEC) {
27 module,
28 ast->token->line,
29 ast->token->column,
30 ast->token->lexeme.length,
31 "Unexpected token where is expected a bitfield specification's field list or expression."
32 );
33
34 return;
35 }
36
37 dstring_copy(&spec->name, ast->token->lexeme.data);
38 spec->type = _spec_type(ast);
39
40 switch (spec->type) {
41 case FT_SPEC:
43 eval_bitfield_spec(spec->spec, module, &field_spec->children[0], variables);
44 break;
45 case FT_LITERAL:
46 spec->value = eval_expression(variables, module, field_spec->children);
47 break;
48 case FT_IDENTIFIER:
49 dstring_copy(&spec->identifier, field_spec->children[0].token->lexeme.data);
50 break;
51 case FT_FIELDS:
52 for (int i = 0; i < field_spec->children_count; i++) {
53 mir_bitfield_spec_t* field =
55 eval_bitfield_spec(field, module, &field_spec->children[i], variables);
56 }
57 break;
58 }
59}
void dstring_copy(dstring_t *string, const char *source)
Copies the content of source to the dstring.
Definition dstring.c:50
void eval_bitfield_spec(mir_bitfield_spec_t *spec, module_t *module, ast_node_t *ast, hashtable_t *variables)
Evaluates a bitfield specification expression.
mir_bitfield_spec_type_t _spec_type(ast_node_t *spec)
mir_bitfield_spec_t * mir_bitfield_spec_set_spec(mir_bitfield_spec_t *spec, const char *name, mir_bitfield_spec_type_t type)
Set the bitfield spec's sub bitfield spec.
Definition mir.c:326
mir_bitfield_spec_t * mir_bitfield_spec_add_field(mir_bitfield_spec_t *spec, const char *name, mir_bitfield_spec_type_t type)
Add a new bitfield spec's field to the given bitfield spec.
Definition mir.c:304
mir_bitfield_spec_type_t type
Specify the type of this bitfield specification.
Definition mir.h:70
dstring_t identifier
Bitfield's value identifier.
Definition mir.h:71
struct mir_bitfield_spec * spec
Bitfield's list of field specifications.
Definition mir.h:73
dstring_t name
Name of the bitfield.
Definition mir.h:69
int64_t value
Bitfield's literal value.
Definition mir.h:72
@ NT_FIELD_SPEC
Definition ast.h:15
@ NT_BITFIELD_SPEC
Definition ast.h:13
@ FT_LITERAL
Bitfield spec value is a literal value.
Definition mir.h:32
@ FT_FIELDS
Bitfied spec value has a body with a list of fields.
Definition mir.h:28
@ FT_SPEC
Bitfield spec value is a bitfield spec.
Definition mir.h:34
@ FT_IDENTIFIER
Bitfield spec value is a identifier.
Definition mir.h:30
struct mir_bitfield_spec mir_bitfield_spec_t
A bitfield or bitfield's field declaration.

◆ eval_expression()

int64_t eval_expression ( hashtable_t * variables,
module_t * module,
ast_node_t * ast )

Evaluates a mathetical expression.

Parameters
variablesThe hashtable with the declared variables.
moduleMya module where this expression is in.
astThe AST node where start the expression.

Definition at line 15 of file eval_expression.c.

16{
17 int64_t result;
18
19 if (ast->type != NT_EXPRESSION) {
21 module,
22 ast->token->line,
23 ast->token->column,
24 ast->token->lexeme.length,
25 "Unexpected token inside an expression."
26 );
27
28 return 0;
29 }
30
31 switch (ast->token->type) {
32 case TK_OPEN_PARENS:
33 return eval_expression(variables, module, ast->children);
34 case TK_NUMBER:
35 return ast->token->value;
36 case TK_IDENTIFIER:
37 if (hashtable_get(variables, ast->token->lexeme.data, &result) != ERR_OK) {
38 module_add_error(module, ast->token->line, ast->token->column, ast->token->lexeme.length, "Undefined variable.");
39 return 0;
40 }
41
42 return result;
43 case TK_OPERATOR:
44 bool is_binary = (ast->children_count == 2);
45 ast_node_t* a = &ast->children[0];
46
47 if (is_binary) {
48 ast_node_t* b = &ast->children[1];
49 return _op_binary_eval(
50 eval_expression(variables, module, a),
51 ast->token->value,
52 eval_expression(variables, module, b)
53 );
54 }
55
56 return _op_unary_eval(ast->token->value, eval_expression(variables, module, a));
57 default:
58 return 0;
59 }
60}
@ ERR_OK
Definition err.h:15
int64_t _op_unary_eval(operator_t op, int64_t a)
int64_t _op_binary_eval(int64_t a, operator_t op, int64_t b)
error_code_t hashtable_get(hashtable_t *hashtable, const char *key, int64_t *value)
Get the value of the specified key inside the hashtable.
Definition hashtable.c:73
token_type_t type
Token type.
Definition token.h:35
@ NT_EXPRESSION
Definition ast.h:14
@ TK_NUMBER
Definition token.h:21
@ TK_IDENTIFIER
Definition token.h:19
@ TK_OPEN_PARENS
Definition token.h:24
@ TK_OPERATOR
Definition token.h:25

◆ eval_include()

void eval_include ( mir_t * mir,
module_t * module,
ast_node_t * ast )

Evaluates an include statement.

Parameters
mirThe MIR struct where to add the intermediate represetation.
moduleMya module where the statement is in.
astThe AST node where start the statement.

Definition at line 8 of file eval_include.c.

9{
10 if (ast->type != NT_STATEMENT || ast->token->value != KEY_INCLUDE) {
12 module,
13 ast->token->line,
14 ast->token->column,
15 ast->token->lexeme.length,
16 "Unexpected token where is expected an include statement."
17 );
18
19 return;
20 }
21
22 token_t* token_path = ast->children[0].token;
24 if (module_init(submodule, token_path->lexeme.data) != ERR_OK) {
26 module,
27 token_path->line,
28 token_path->column,
29 token_path->lexeme.length,
30 "File not found. You should use an absolute path or a relative path from the current working directory."
31 );
32
33 return;
34 }
35
36 if (mya_lexer(submodule) != ERR_OK) {
37 return;
38 }
39
40 if (mya_parser(submodule) != ERR_OK) {
41 return;
42 }
43
44 mya_evaluator(mir, submodule);
45}
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-memo...
Definition evaluator.c:6
@ KEY_INCLUDE
Definition keywords.h:7
error_code_t module_init(module_t *module, const char *filepath)
Initialize a module struct.
Definition module.c:18
module_t * module_add_submodule(module_t *module)
Add submodule for the given module.
Definition module.c:108
error_code_t mya_parser(module_t *module)
Make the syntactical analysis on the given module and construct the AST.
Definition parser.c:12
error_code_t mya_lexer(module_t *module)
Make the lexical analysis on the given module.
Definition lexer.c:53
struct module module_t
Struct that represents a Mya module.
struct token token_t
Struct for a Mya token.

◆ eval_inst()

void eval_inst ( mir_t * mir,
module_t * module,
ast_node_t * ast )

Evaluates an inst statement.

Parameters
mirThe MIR struct where to add the intermediate represetation.
moduleMya module where the statement is in.
astThe AST node where start the statement.

◆ eval_register()

void eval_register ( mir_t * mir,
module_t * module,
ast_node_t * ast )

Evaluates a register statement.

Parameters
mirThe MIR struct where to add the intermediate represetation.
moduleMya module where the statement is in.
astThe AST node where start the statement.

Definition at line 7 of file eval_register.c.

8{
9 if (ast->type != NT_STATEMENT || ast->token->value != KEY_REGISTER) {
11 module,
12 ast->token->line,
13 ast->token->column,
14 ast->token->lexeme.length,
15 "Unexpected token where is expected a register statement."
16 );
17
18 return;
19 }
20
21 ast_node_t* node_name = &ast->children[0];
22 ast_node_t* node_size = &ast->children[1];
23 ast_node_t* node_spec = &ast->children[2];
24
25 int64_t size = eval_expression(&mir->variables, module, node_size);
26 if (size < 0 || size > 4096) {
28 module,
29 node_size->token->line,
30 node_size->token->column,
31 node_size->token->lexeme.length,
32 "Register size should be between 0 and 4096."
33 );
34
35 return;
36 }
37
38 mir_register_t* reg = mir_add_register(mir, node_name->token->lexeme.data, size);
39 eval_bitfield_spec(&reg->spec, module, node_spec, &mir->variables);
40}
@ KEY_REGISTER
Definition keywords.h:9
mir_register_t * mir_add_register(mir_t *mir, const char *name, uint32_t size)
Add a new register declaration for the specified MIR.
Definition mir.c:136
mir_bitfield_spec_t spec
Register's bitfield specification.
Definition mir.h:85
struct mir_register mir_register_t
Register declaration.

◆ eval_set()

void eval_set ( mir_t * mir,
module_t * module,
ast_node_t * ast )

Evaluates a set statement.

Parameters
mirThe MIR struct where to add the intermediate represetation.
moduleMya module where the statement is in.
astThe AST node where start the statement.

Definition at line 8 of file eval_set.c.

9{
10 if (ast->type != NT_STATEMENT || ast->token->value != KEY_SET) {
12 module,
13 ast->token->line,
14 ast->token->column,
15 ast->token->lexeme.length,
16 "Unexpected token where is expected a set statement."
17 );
18
19 return;
20 }
21
22 ast_node_t* node_var = &ast->children[0];
23 ast_node_t* node_value = &ast->children[1];
24
25 int64_t value = eval_expression(&mir->variables, module, node_value);
26 hashtable_set(&mir->variables, node_var->token->lexeme.data, value);
27}
void hashtable_set(hashtable_t *hashtable, const char *key, int64_t value)
Set the value of the specified key inside the hashtable.
Definition hashtable.c:51
@ KEY_SET
Definition keywords.h:10