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
+8 -2
View File
@@ -1,12 +1,18 @@
CC=gcc
CC_FLAGS=-O2 -Wall -Wextra
CC_FLAGS=-O2 -Wall -Wextra -g
SRCDIR=src
INCLUDEDIR=include
FILES=$(SRCDIR)/main.c \
$(SRCDIR)/scanner.c \
$(SRCDIR)/parser.c
$(SRCDIR)/parser.c \
$(SRCDIR)/expr.c \
$(SRCDIR)/label.c \
$(SRCDIR)/ttk_register.c \
$(SRCDIR)/comment.c \
$(SRCDIR)/oper.c \
$(SRCDIR)/value.c
scanner:
# this is case insensitive!!
+11
View File
@@ -0,0 +1,11 @@
#ifndef COMMENT_H
#define COMMENT_H
struct comment {
char *text;
};
struct comment * comment_create(char *text);
#endif
+28
View File
@@ -0,0 +1,28 @@
#ifndef EXPR_H
#define EXPR_H
#include "oper.h"
#include "ttk_register.h"
#include "value.h"
#include "label.h"
#include "comment.h"
typedef enum {
INSTRUCTION,
LABEL_DEF,
COMMENT
} expr_t;
struct expr {
expr_t kind;
struct label *label;
struct oper *oper;
struct ttk_register *first_arg;
struct value *second_arg;
struct comment *comment;
struct expr *next;
};
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);
#endif
+19
View File
@@ -0,0 +1,19 @@
#ifndef LABEL_H
#define LABEL_H
#include "expr.h"
typedef enum {
LABEL_CONST,
LABEL_TAG
} label_t;
struct label {
label_t kind;
const char *name;
int value;
};
struct label * label_create(label_t kind, char *name, int value);
#endif
+22
View File
@@ -0,0 +1,22 @@
#ifndef OPER_H
#define OPER_H
#include "ttk_register.h"
typedef enum {
OPER_DATA,
OPER_AR,
OPER_LOGIC,
OPER_BRANCH,
OPER_STACK,
OPER_SYS
} oper_t;
struct oper {
oper_t kind;
char* oper_name;
};
struct oper * oper_create(oper_t kind, char* oper_name);
#endif
+20 -2
View File
@@ -79,7 +79,25 @@ extern int yydebug;
/* Value type. */
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef int YYSTYPE;
union YYSTYPE
{
#line 39 "src/parser.bison"
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;
#line 98 "include/token.h"
};
typedef union YYSTYPE YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define YYSTYPE_IS_DECLARED 1
#endif
@@ -88,7 +106,7 @@ typedef int YYSTYPE;
extern YYSTYPE yylval;
int yyparse (void);
int yyparse (struct expr *parse_result);
#endif /* !YY_YY_INCLUDE_TOKEN_H_INCLUDED */
+12
View File
@@ -0,0 +1,12 @@
#ifndef REGISTER_H
#define REGISTER_H
struct ttk_register {
int id;
int value;
};
struct ttk_register * ttk_register_create(char* id, int value);
int parse_register_num(char *name);
#endif
+42
View File
@@ -0,0 +1,42 @@
#ifndef VALUE_H
#define VALUE_H
#include "ttk_register.h"
#include "label.h"
typedef enum {
REGISTER,
NUMBER,
LABEL
} value_t;
typedef enum {
NONE,
INDEXED
} index_t;
typedef enum {
DIRECT,
IMMEDIATE,
INDIRECT
} addr_mode_t;
struct value {
addr_mode_t addr_mode;
index_t indexing_mode;
struct pure_value *value;
struct ttk_register *index_register;
};
struct pure_value {
value_t kind;
struct ttk_register *ttk_register;
int number;
struct label *label;
};
struct value * value_create(addr_mode_t addr_m, index_t i_m, struct pure_value *value, struct ttk_register *i_reg);
struct pure_value * pure_value_create(value_t kind, struct ttk_register *ttk_reg, int num, struct label *l);
addr_mode_t parse_addr_mode(char addr_mode);
#endif
+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;
}
}