mirror of
https://github.com/iritmaximus/ttk91-compiler.git
synced 2026-10-12 19:13:40 +03:00
implemented ast creation
This commit is contained in:
+8
-2
@@ -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!!
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
#ifndef COMMENT_H
|
||||
#define COMMENT_H
|
||||
|
||||
|
||||
struct comment {
|
||||
char *text;
|
||||
};
|
||||
|
||||
struct comment * comment_create(char *text);
|
||||
|
||||
#endif
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
@@ -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");
|
||||
|
||||
@@ -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
@@ -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; }
|
||||
;
|
||||
|
||||
%%
|
||||
|
||||
@@ -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';
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user