1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
|
#include "parser.h"
#include <backend.h>
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include "irm.h"
#include "lex.h"
int parser_within_bounds(struct parser_config *pc)
{
return pc->pos < pc->size && pc->tokens[pc->pos].type != T_EOF;
}
int parser_within_obounds(struct parser_config *pc, size_t o)
{
return (pc->pos + o) < pc->size && pc->tokens[pc->pos + o].type != T_EOF;
}
struct token parser_peek(struct parser_config *pc, size_t o)
{
assert(pc != NULL);
if(!parser_within_obounds(pc, o)) return pc->tokens[pc->pos];
return pc->tokens[pc->pos + o];
}
void parser_throw(struct parser_config *pc, const char *err)
{
pc->state = PARSER_PANIC;
DEBUG("%s", err);
irm_panic(&pc->irm);
}
int parser_expect(struct parser_config *pc, uint64_t type, const char *err)
{
assert(pc != NULL);
if(parser_peek(pc, 0).type == type)
return 0;
parser_throw(pc, err);
return 1;
}
int parser_expect_condthrow(struct parser_config *pc, uint64_t type, const char *err)
{
assert(pc != NULL);
if(parser_peek(pc, 0).type == type)
return 0;
if(err[0] != '\0')
parser_throw(pc, err);
return 1;
}
struct token parser_advance(struct parser_config *pc)
{
assert(pc != NULL);
if(!parser_within_bounds(pc)) return pc->tokens[pc->pos];
pc->pos++;
return pc->tokens[pc->pos];
}
void parser_literal(struct parser_config *pc)
{
assert(pc != NULL);
struct token t = parser_peek(pc, 0);
if(t.type == T_NUMBER) {
uint64_t a = atoi(t.me.buf);
irm_push_64v(&pc->irm, NUMBER64, a);
DEBUG("Pushed into the irm: %lld.\n", a);
parser_advance(pc);
return;
}
parser_throw(pc, "Invalid expression\n");
}
uint64_t parser_type_to_irm_inst(struct parser_config *pc, uint64_t type)
{
switch(type) {
case T_TYPE_G64:
return VAR_DECL_QWORD;
case T_TYPE_G32:
return VAR_DECL_DWORD;
case T_TYPE_G16:
return VAR_DECL_WORD;
case T_TYPE_G8:
return VAR_DECL_BYTE;
default:
parser_throw(pc, "An invalid type detected... defaulting storage to QWORD.");
return VAR_DECL_QWORD;
}
}
void parser_assign_stmt(struct parser_config *pc)
{
struct string_view symbol = parser_peek(pc, 0).me;
irm_push(&pc->irm, VAR_ASSIGN);
irm_push_lookup_sym(&pc->irm, SYM_VAR, symbol);
parser_advance(pc);
parser_expect(pc, T_EQUAL_SIGN, "Assignment operation requires an equal sign after the symbol.");
parser_advance(pc);
parser_literal(pc);
}
void parser_decl_stmt(struct parser_config *pc)
{
struct token t = parser_peek(pc, 0);
if(!(t.type & T_TYPE)) {
parser_throw(pc, "Declaration statement must begin with a type!");
parser_advance(pc);
return;
}
uint64_t type = parser_peek(pc, 0).type;
irm_push(&pc->irm, parser_type_to_irm_inst(pc, type));
parser_advance(pc);
parser_expect(pc, T_ID, "An identifier must follow a type in a declaration statement.");
struct string_view symbol_name = parser_peek(pc, 0).me;
irm_push_sym(&pc->irm, SYM_VAR, symbol_name);
parser_advance(pc);
parser_expect(pc, T_EQUAL_SIGN, "Equal sign must be used to assign a value to a locator");
parser_advance(pc);
parser_literal(pc);
}
void parser_stmt(struct parser_config *pc)
{
struct token t = parser_peek(pc, 0);
if(t.type & T_TYPE) {
parser_decl_stmt(pc);
} else if(t.type == T_ID) {
parser_assign_stmt(pc);
} else {
parser_throw(pc,
"Invalid statement, can only be declaration "
"or assignment.");
}
irm_push(&pc->irm, STMT_DONE); // PUSH STATEMENT DONE SIGNAL
irm_stmt_done(&pc->irm); // TRIGGER SIGNAL
parser_expect(pc, T_SEMICOL, "Statement must end with a semicolon.\n");
parser_advance(pc);
}
void parse_compound_stmt(struct parser_config *pc)
{
assert(pc != NULL);
irm_stmt_enter_scope(&pc->irm);
irm_stmt_leave_scope(&pc->irm);
}
void parser_parse(struct parser_config *pc)
{
assert(pc != NULL);
pc->state = PARSER_GRACEFUL;
irm_init(&pc->irm);
while(parser_within_bounds(pc)) {
parser_stmt(pc);
}
}
|