implemented ast creation

This commit is contained in:
Aaro Koivukangas
2024-08-14 21:50:08 +02:00
parent 67399c071d
commit 407f1d75a7
16 changed files with 361 additions and 38 deletions
+11
View File
@@ -0,0 +1,11 @@
#include <stdlib.h>
#include "comment.h"
struct comment * comment_create(char *text)
{
struct comment *c = malloc(sizeof(*c));
c->text = text;
return c;
}
+17
View File
@@ -0,0 +1,17 @@
#include <stdlib.h>
#include "expr.h"
struct expr * expr_create(expr_t kind, struct label *l, struct oper *o, struct ttk_register *f_arg, struct value *s_arg, struct comment *c, struct expr *n)
{
struct expr * e = malloc(sizeof(*e));
e->kind = kind;
e->label = l;
e->oper = o;
e->first_arg = f_arg;
e->second_arg = s_arg;
e->comment = c;
e->next = n;
return e;
}
+13
View File
@@ -0,0 +1,13 @@
#include <stdlib.h>
#include "label.h"
struct label * label_create(label_t kind, char *name, int value)
{
struct label *l = malloc(sizeof(*l));
l->kind = kind;
l->name = name;
l->value = value;
return l;
}
+6 -2
View File
@@ -1,5 +1,7 @@
#include "token.h"
#include <stdlib.h>
#include <stdio.h>
#include "token.h"
#include "expr.h"
#define FILENAME "../docs/example-file-harder.k91"
@@ -20,7 +22,9 @@ int main()
return 1;
}
if (yyparse() == 0) {
struct expr *parse_result = malloc(sizeof(*parse_result));
if (yyparse(parse_result) == 0) {
printf("Parse succesful :)\n");
} else {
printf("Parse failed\n");
+13
View File
@@ -0,0 +1,13 @@
#include <stdlib.h>
#include "oper.h"
struct oper * oper_create(oper_t kind, char* oper_name)
{
struct oper *o = malloc(sizeof(*o));
o->kind = kind;
o->oper_name = oper_name;
return o;
}
+75 -32
View File
@@ -1,10 +1,19 @@
/* TODO support tags to jump to different sections */
%{
#include <stdio.h>
extern int yylineno;
#include <stdio.h>
#include "comment.h"
#include "expr.h"
#include "label.h"
#include "oper.h"
#include "value.h"
extern int yylineno;
%}
%define parse.error verbose
%parse-param { struct expr *parse_result }
%token TOKEN_REGISTER
%token TOKEN_STACK_REGISTER
@@ -26,50 +35,84 @@
%token TOKEN_COMMENT
%token TOKEN_ERROR
%union {
struct expr *expr;
struct oper *oper;
struct ttk_register *ttk_register;
struct value *value;
struct pure_value *pure_value;
struct label *label;
struct comment *comment;
char* name;
int num;
char character;
}
%type <expr> program expr_list expr
%type <oper> oper
%type <ttk_register> ttk_register
%type <value> value
%type <pure_value> pure_value
%type <label> label
%type <num> num_value
%type <name> TOKEN_REGISTER TOKEN_STACK_REGISTER
%type <name> TOKEN_OPER_DATA TOKEN_OPER_AR TOKEN_OPER_LOGIC TOKEN_OPER_BRANCH TOKEN_OPER_STACK TOKEN_OPER_SYS
%type <name> TOKEN_LABEL TOKEN_SYS_NUM
%type <character> TOKEN_PAREN_L TOKEN_PAREN_R TOKEN_ADDR_M TOKEN_SIGN
%type <num> TOKEN_NUMBER
%type <name> TOKEN_COMMENT
%%
program : expr
| program expr
;
program : expr_list { parse_result = $1; }
;
expr : oper register TOKEN_COMMA second_arg
| oper value
| TOKEN_LABEL TOKEN_COMP_OPER num_value
| TOKEN_LABEL expr
| comment
;
expr_list : expr expr_list { $$ = $1; $1->next = $2; }
| { $$ = NULL; }
;
oper : TOKEN_OPER_DATA
| TOKEN_OPER_AR
| TOKEN_OPER_LOGIC
| TOKEN_OPER_BRANCH
| TOKEN_OPER_STACK
| TOKEN_OPER_SYS
;
expr : oper ttk_register TOKEN_COMMA value { $$ = expr_create(INSTRUCTION, NULL, $1, $2, $4, NULL, NULL); }
| oper value { $$ = expr_create(INSTRUCTION, NULL, $1, NULL, $2, NULL, NULL); }
| TOKEN_LABEL TOKEN_COMP_OPER num_value { $$ = expr_create(LABEL_DEF, label_create(LABEL_CONST, $1, 0), NULL, NULL, NULL, NULL, NULL); /* TODO implement this properly */ }
| TOKEN_LABEL oper ttk_register TOKEN_COMMA value { $$ = expr_create(INSTRUCTION, label_create(LABEL_TAG,$1, 0), $2, $3, $5, NULL, NULL); /* TODO FIXME labels have always value 0 */ }
| TOKEN_LABEL oper value { $$ = expr_create(INSTRUCTION, label_create(LABEL_TAG,$1, 0), $2, NULL, $3, NULL, NULL); }
| TOKEN_COMMENT { $$ = expr_create(COMMENT, NULL, NULL, NULL, NULL, comment_create($1), NULL); }
;
register : TOKEN_REGISTER
| TOKEN_STACK_REGISTER
oper : TOKEN_OPER_DATA { $$ = oper_create(OPER_DATA, $1); }
| TOKEN_OPER_AR { $$ = oper_create(OPER_AR, $1); }
| TOKEN_OPER_LOGIC { $$ = oper_create(OPER_LOGIC, $1); }
| TOKEN_OPER_BRANCH { $$ = oper_create(OPER_BRANCH, $1); }
| TOKEN_OPER_STACK { $$ = oper_create(OPER_STACK, $1); }
| TOKEN_OPER_SYS { $$ = oper_create(OPER_SYS, $1); }
;
ttk_register: TOKEN_REGISTER { $$ = ttk_register_create($1, 0); }
| TOKEN_STACK_REGISTER { $$ = ttk_register_create($1, 0); }
;
second_arg : value TOKEN_PAREN_L register TOKEN_PAREN_R
| value
| TOKEN_ADDR_M value TOKEN_PAREN_L register TOKEN_PAREN_R
| TOKEN_ADDR_M value
| TOKEN_PAREN_L register TOKEN_PAREN_R
value : pure_value TOKEN_PAREN_L ttk_register TOKEN_PAREN_R { value_create(DIRECT, INDEXED, $1, $3); }
| pure_value { value_create(DIRECT, NONE, $1, NULL); }
| TOKEN_ADDR_M pure_value TOKEN_PAREN_L ttk_register TOKEN_PAREN_R { value_create(parse_addr_mode($1), INDEXED, $2, $4); }
| TOKEN_ADDR_M pure_value { value_create(parse_addr_mode($1), NONE, $2, NULL); }
| TOKEN_PAREN_L ttk_register TOKEN_PAREN_R { value_create(DIRECT, NONE, NULL, $2); }
;
value : register
| num_value
| TOKEN_LABEL
| TOKEN_SYS_NUM
pure_value : ttk_register { $$ = pure_value_create(REGISTER, $1, 0, NULL); }
| num_value { $$ = pure_value_create(NUMBER, NULL, $1, NULL); }
| label { $$ = pure_value_create(LABEL, NULL, 0, $1); }
;
num_value : TOKEN_SIGN TOKEN_NUMBER
| TOKEN_NUMBER
label : TOKEN_LABEL { $$ = label_create(LABEL_CONST, $1, 0); }
| TOKEN_SYS_NUM { $$ = label_create(LABEL_CONST, $1, 0); /* TODO FIXME */ }
;
comment : TOKEN_COMMENT
num_value : TOKEN_SIGN TOKEN_NUMBER { $$ = -$2; }
| TOKEN_NUMBER { $$ = $1; }
;
%%
+22
View File
@@ -0,0 +1,22 @@
#include <stdlib.h>
#include "ttk_register.h"
struct ttk_register * ttk_register_create(char* name, int value)
{
struct ttk_register * r = malloc(sizeof(*r));
r->id = parse_register_num(name);
r->value = value;
return r;
}
int parse_register_num(char* name)
{
if (!name) {
return -1;
}
char num = name[1]; // registers have the format RX, 'R' + X 0-7
return num - '0';
}
+42
View File
@@ -0,0 +1,42 @@
#include <stdlib.h>
#include "value.h"
struct value * value_create(addr_mode_t a_m, index_t i_m, struct pure_value *p_v, struct ttk_register *i_reg)
{
struct value *v = malloc(sizeof(*v));
v->addr_mode = a_m;
v->indexing_mode = i_m;
v->value = p_v;
v->index_register = i_reg;
return v;
}
struct pure_value * pure_value_create(value_t kind, struct ttk_register *ttk_reg, int num, struct label *l)
{
struct pure_value *v = malloc(sizeof(*v));
v->kind = kind;
v->ttk_register = ttk_reg;
v->number = num;
v->label = l;
return v;
}
addr_mode_t parse_addr_mode(char addr_mode)
{
if (addr_mode == '=')
{
return IMMEDIATE;
}
if (addr_mode == '@')
{
return INDIRECT;
}
else {
return DIRECT;
}
}