diff --git a/c/include/expr.h b/c/include/expr.h index 6af34e9..b63b534 100644 --- a/c/include/expr.h +++ b/c/include/expr.h @@ -25,5 +25,14 @@ struct expr { }; 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); +void expr_copy(struct expr *orig, struct expr *copy); + +struct expr *expr_create_instruction(struct oper *o, struct ttk_register *ttk_reg, struct value *v); +struct expr *expr_create_instruction_one_arg(struct oper *o, struct value *v); +struct expr *expr_create_labeled_instruction(struct label *l, struct oper *o, struct ttk_register *ttk_reg, struct value *v); +struct expr *expr_create_labeled_instruction_one_arg(struct label *l, struct oper *o, struct value *v); +struct expr *expr_create_compiler_instruction(struct label *l, struct oper *o, struct value *v); +struct expr *expr_create_compiler_instruction_raw_label_oper_value(char* label, char *o, int value); +struct expr *expr_create_comment(struct comment *c); #endif diff --git a/c/include/label.h b/c/include/label.h index 520a282..65a8fdf 100644 --- a/c/include/label.h +++ b/c/include/label.h @@ -10,10 +10,13 @@ typedef enum { struct label { label_t kind; - const char *name; + char *name; int value; }; -struct label * label_create(label_t kind, char *name, int value); +struct label * label_create(label_t kind, char* name, int value); +struct label * label_create_const(char* name); +struct label * label_create_const_sys(char* name); +struct label * label_create_tag(char* name); #endif diff --git a/c/include/oper.h b/c/include/oper.h index 9a43ef4..6ab7a28 100644 --- a/c/include/oper.h +++ b/c/include/oper.h @@ -9,7 +9,8 @@ typedef enum { OPER_LOGIC, OPER_BRANCH, OPER_STACK, - OPER_SYS + OPER_SYS, + OPER_COMPILER } oper_t; struct oper { @@ -18,5 +19,12 @@ struct oper { }; struct oper * oper_create(oper_t kind, char* oper_name); +struct oper * oper_create_data(char* oper_name); +struct oper * oper_create_arithmetic(char* oper_name); +struct oper * oper_create_logic(char* oper_name); +struct oper * oper_create_branch(char* oper_name); +struct oper * oper_create_stack(char* oper_name); +struct oper * oper_create_sys(char* oper_name); +struct oper * oper_create_compiler(char* oper_name); #endif diff --git a/c/include/ttk_register.h b/c/include/ttk_register.h index 88e76b4..9d7fd59 100644 --- a/c/include/ttk_register.h +++ b/c/include/ttk_register.h @@ -14,5 +14,7 @@ struct ttk_register { struct ttk_register * ttk_register_create(ttk_register_t kind, char* id, int value); int parse_register_num(char *name, ttk_register_t kind); +struct ttk_register * ttk_register_create_register(char* name); +struct ttk_register * ttk_register_create_stack_register(char* name); #endif diff --git a/c/include/value.h b/c/include/value.h index 5a7961a..e73eae3 100644 --- a/c/include/value.h +++ b/c/include/value.h @@ -37,6 +37,17 @@ struct pure_value { }; struct value * value_create(addr_mode_t addr_m, index_t i_m, struct pure_value *value, struct ttk_register *i_reg); +struct value * value_create_direct_value(struct pure_value *p_v); +struct value * value_create_direct_indexed(struct pure_value *p_v, struct ttk_register *ttk_reg); +struct value * value_create_address_mode_indexed(char addr_mode, struct pure_value *p_v, struct ttk_register *ttk_reg); +struct value * value_create_address_mode(char addr_mode, struct pure_value *p_v); +struct value * value_create_direct_register(struct ttk_register *ttk_reg); + + +struct pure_value * pure_value_create_ttk_register(struct ttk_register *ttk_reg); +struct pure_value * pure_value_create_value(int value); +struct pure_value * pure_value_create_label(struct label *l); + 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); diff --git a/c/src/comment.c b/c/src/comment.c index f054891..02fca5e 100644 --- a/c/src/comment.c +++ b/c/src/comment.c @@ -1,4 +1,5 @@ #include +#include #include "comment.h" struct comment * comment_create(char *text) diff --git a/c/src/label.c b/c/src/label.c index 281c934..5c1e844 100644 --- a/c/src/label.c +++ b/c/src/label.c @@ -1,16 +1,23 @@ #include +#include +#include #include "label.h" -struct label * label_create(label_t kind, char *name, int value) +struct label * label_create(label_t kind, char* name, int value) { if (!name) return NULL; struct label *l = malloc(sizeof(*l)); + l->kind = kind; l->name = name; l->value = value; return l; } + +struct label * label_create_const(char* name) { return label_create(LABEL_CONST, name, 0); } +struct label * label_create_const_sys(char* name) { return label_create(LABEL_CONST, name, 0); } // FIXME value +struct label * label_create_tag(char* name) { return label_create(LABEL_TAG, name, 0); } // FIXME also this diff --git a/c/src/main.c b/c/src/main.c index 76f6d7e..27bbdce 100644 --- a/c/src/main.c +++ b/c/src/main.c @@ -4,6 +4,8 @@ #include "expr.h" #define FILENAME "../docs/example-file-harder.k91" +//#define FILENAME "../docs/example-file.k91" +//#define FILENAME "../docs/example-file-simple.k91" // scanner extern FILE *yyin; diff --git a/c/src/oper.c b/c/src/oper.c index 42b8c12..182fd86 100644 --- a/c/src/oper.c +++ b/c/src/oper.c @@ -7,11 +7,16 @@ struct oper * oper_create(oper_t kind, char* oper_name) { struct oper *o = malloc(sizeof(*o)); - char *name_copy = malloc(sizeof(char) * (strlen(oper_name)+1)); - strcpy(name_copy, oper_name); - o->kind = kind; - o->oper_name = name_copy; + o->oper_name = oper_name; return o; } + +struct oper * oper_create_data(char* oper_name) { return oper_create(OPER_DATA, oper_name); } +struct oper * oper_create_arithmetic(char* oper_name) { return oper_create(OPER_AR, oper_name); } +struct oper * oper_create_logic(char* oper_name) { return oper_create(OPER_LOGIC, oper_name); } +struct oper * oper_create_branch(char* oper_name) { return oper_create(OPER_BRANCH, oper_name); } +struct oper * oper_create_stack(char* oper_name) { return oper_create(OPER_STACK, oper_name); } +struct oper * oper_create_sys(char* oper_name) { return oper_create(OPER_SYS, oper_name); } +struct oper * oper_create_compiler(char* oper_name) { return oper_create(OPER_COMPILER, oper_name); } diff --git a/c/src/parser.bison b/c/src/parser.bison index 8562818..cc1ea79 100644 --- a/c/src/parser.bison +++ b/c/src/parser.bison @@ -59,7 +59,7 @@ extern int yylineno; %type num_value %type TOKEN_REGISTER TOKEN_STACK_REGISTER -%type TOKEN_OPER_DATA TOKEN_OPER_AR TOKEN_OPER_LOGIC TOKEN_OPER_BRANCH TOKEN_OPER_STACK TOKEN_OPER_SYS +%type TOKEN_OPER_DATA TOKEN_OPER_AR TOKEN_OPER_LOGIC TOKEN_OPER_BRANCH TOKEN_OPER_STACK TOKEN_OPER_SYS TOKEN_COMP_OPER %type TOKEN_LABEL TOKEN_SYS_NUM %type TOKEN_PAREN_L TOKEN_PAREN_R TOKEN_ADDR_M TOKEN_SIGN %type TOKEN_NUMBER @@ -70,45 +70,45 @@ extern int yylineno; program : expr_list { expr_copy(parse_result, $1); } ; -expr_list : expr_list expr { $$ = $2; $2->next = $1; } +expr_list : expr expr_list { $$ = $1; $1->next = $2; } | { $$ = NULL; } ; -expr : oper ttk_register TOKEN_COMMA value { $$ = expr_create(INSTRUCTION, NULL, $1, $2, $4, NULL, NULL); } - | oper value { $$ = expr_create(INSTRUCTION_ONE_ARG, 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); } +expr : oper ttk_register TOKEN_COMMA value { $$ = expr_create_instruction($1, $2, $4); } + | oper value { $$ = expr_create_instruction_one_arg($1, $2); } + | TOKEN_LABEL TOKEN_COMP_OPER num_value { $$ = expr_create_compiler_instruction_raw_label_oper_value($1, $2, $3); /* TODO implement this properly */ } + | TOKEN_LABEL oper ttk_register TOKEN_COMMA value { $$ = expr_create_labeled_instruction(label_create_tag($1), $2, $3, $5); /* TODO FIXME labels have always value 0 */ } + | TOKEN_LABEL oper value { $$ = expr_create_labeled_instruction_one_arg(label_create_tag($1), $2, $3); /* TODO FIXME labels have always value 0 */ } + | TOKEN_COMMENT { $$ = expr_create_comment(comment_create($1)); } ; -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); } +oper : TOKEN_OPER_DATA { $$ = oper_create_data($1); } + | TOKEN_OPER_AR { $$ = oper_create_arithmetic($1); } + | TOKEN_OPER_LOGIC { $$ = oper_create_logic($1); } + | TOKEN_OPER_BRANCH { $$ = oper_create_branch($1); } + | TOKEN_OPER_STACK { $$ = oper_create_stack($1); } + | TOKEN_OPER_SYS { $$ = oper_create_sys($1); } ; -ttk_register: TOKEN_REGISTER { $$ = ttk_register_create(TTK_REGISTER, $1, 0); } - | TOKEN_STACK_REGISTER { $$ = ttk_register_create(STACK_TTK_REGISTER, $1, 0); } +ttk_register: TOKEN_REGISTER { $$ = ttk_register_create_register($1); } + | TOKEN_STACK_REGISTER { $$ = ttk_register_create_stack_register($1); } ; -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 : pure_value TOKEN_PAREN_L ttk_register TOKEN_PAREN_R { $$ = value_create_direct_indexed($1, $3); } + | pure_value { $$ = value_create_direct_value($1); } + | TOKEN_ADDR_M pure_value TOKEN_PAREN_L ttk_register TOKEN_PAREN_R { $$ = value_create_address_mode_indexed($1, $2, $4); } + | TOKEN_ADDR_M pure_value { $$ = value_create_address_mode($1, $2); } + | TOKEN_PAREN_L ttk_register TOKEN_PAREN_R { $$ = value_create_direct_register($2); } ; -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); } +pure_value : ttk_register { $$ = pure_value_create_ttk_register($1); } + | num_value { $$ = pure_value_create_value($1); } + | label { $$ = pure_value_create_label($1); } ; -label : TOKEN_LABEL { $$ = label_create(LABEL_CONST, $1, 0); } - | TOKEN_SYS_NUM { $$ = label_create(LABEL_CONST, $1, 0); /* TODO FIXME */ } +label : TOKEN_LABEL { $$ = label_create_const($1); } + | TOKEN_SYS_NUM { $$ = label_create_const_sys($1); /* TODO FIXME */ } ; diff --git a/c/src/scanner.flex b/c/src/scanner.flex index bbb4eb0..b3a9757 100644 --- a/c/src/scanner.flex +++ b/c/src/scanner.flex @@ -1,39 +1,52 @@ %{ +#include +#include #include "token.h" #define YYSTYPE char * + + +int yywrap(); +char* copy_yytext(char* orig); %} %option yylineno %% -;.*$ { yylval.name = yytext; return TOKEN_COMMENT; } +;.*$ { yylval.name = copy_yytext(yytext); return TOKEN_COMMENT; } (" "|\t|\n) /* skip whitespace */ -(@|=) { yylval.name = yytext; return TOKEN_ADDR_M; } +(@|=) { yylval.name = copy_yytext(yytext); return TOKEN_ADDR_M; } \( { return TOKEN_PAREN_L; } \) { return TOKEN_PAREN_R; } , { return TOKEN_COMMA; } -(?i:LOAD|STORE|IN|OUT) { yylval.name = yytext; return TOKEN_OPER_DATA; } /* TODO, currently only in uppercase */ -(?i:ADD|SUB|MUL|DIV|MOD) { yylval.name = yytext; return TOKEN_OPER_AR; } -(?i:AND|OR|XOR|NOT|SHL|SHR|SHRA|COMP) { yylval.name = yytext; return TOKEN_OPER_LOGIC; } -(?i:JUMP|JNEG|JZER|JPOS|JNNEG|JNZER|JNPOS|JLES|JEQU|JGRE|JNLES|JNEQU|JNGRE) { yylval.name = yytext; return TOKEN_OPER_BRANCH; } -(?i:PUSH|POP|PUSHR|POPR) { yylval.name = yytext; return TOKEN_OPER_STACK; } -(?i:CALL|EXIT|SVC|NOP) { yylval.name = yytext; return TOKEN_OPER_SYS; } -(?i:HALT|TIME|DATE|READ|WRITE) { yylval.name = yytext; return TOKEN_SYS_NUM; } -(?i:EQU|DC|DS|DEF) { yylval.name = yytext; return TOKEN_COMP_OPER; } +(?i:LOAD|STORE|IN|OUT) { yylval.name = copy_yytext(yytext); return TOKEN_OPER_DATA; } /* TODO, currently only in uppercase */ +(?i:ADD|SUB|MUL|DIV|MOD) { yylval.name = copy_yytext(yytext); return TOKEN_OPER_AR; } +(?i:AND|OR|XOR|NOT|SHL|SHR|SHRA|COMP) { yylval.name = copy_yytext(yytext); return TOKEN_OPER_LOGIC; } +(?i:JUMP|JNEG|JZER|JPOS|JNNEG|JNZER|JNPOS|JLES|JEQU|JGRE|JNLES|JNEQU|JNGRE) { yylval.name = copy_yytext(yytext); return TOKEN_OPER_BRANCH; } +(?i:PUSH|POP|PUSHR|POPR) { yylval.name = copy_yytext(yytext); return TOKEN_OPER_STACK; } +(?i:CALL|EXIT|SVC|NOP) { yylval.name = copy_yytext(yytext); return TOKEN_OPER_SYS; } +(?i:HALT|TIME|DATE|READ|WRITE) { yylval.name = copy_yytext(yytext); return TOKEN_SYS_NUM; } +(?i:EQU|DC|DS|DEF) { yylval.name = copy_yytext(yytext); return TOKEN_COMP_OPER; } -(?i:SP|FP|PC) { yylval.name = yytext; return TOKEN_STACK_REGISTER; /* TODO possible unnecessary token PC */ } +(?i:SP|FP|PC) { yylval.name = copy_yytext(yytext); return TOKEN_STACK_REGISTER; /* TODO possible unnecessary token PC */ } -(?i:R[0-8]) { yylval.name = yytext; return TOKEN_REGISTER; } +(?i:R[0-8]) { yylval.name = copy_yytext(yytext); return TOKEN_REGISTER; } [0-9]+ { yylval.num = atoi(yytext); return TOKEN_NUMBER; } -([a-öA-Ö][a-öA-Ö0-9_]*) { yylval.name = yytext; return TOKEN_LABEL; } +([a-öA-Ö][a-öA-Ö0-9_]*) { yylval.name = copy_yytext(yytext); return TOKEN_LABEL; } // my god this took time to figure out (copy_yytext) - { return TOKEN_SIGN; } -. { yylval.name = yytext; return TOKEN_ERROR; } +. { yylval.name = copy_yytext(yytext); return TOKEN_ERROR; } %% int yywrap() { return 1; } + +char* copy_yytext(char* orig) +{ + char* copy_name = malloc(sizeof(char) * (strlen(orig)+1)); + strcpy(copy_name, orig); + return copy_name; +} diff --git a/c/src/ttk_register.c b/c/src/ttk_register.c index de1aa31..fda0ad6 100644 --- a/c/src/ttk_register.c +++ b/c/src/ttk_register.c @@ -13,6 +13,17 @@ struct ttk_register * ttk_register_create(ttk_register_t kind, char* name, int v return r; } + +struct ttk_register * ttk_register_create_register(char* name) +{ + return ttk_register_create(TTK_REGISTER, name, 0); +} + +struct ttk_register * ttk_register_create_stack_register(char* name) +{ + return ttk_register_create(STACK_TTK_REGISTER, name, 0); +} + int parse_register_num(char* name, ttk_register_t kind) { if (!name) { diff --git a/c/src/value.c b/c/src/value.c index 664a3bc..a9bf37c 100644 --- a/c/src/value.c +++ b/c/src/value.c @@ -14,6 +14,34 @@ struct value * value_create(addr_mode_t a_m, index_t i_m, struct pure_value *p_v return v; } +struct value * value_create_direct_value(struct pure_value *p_v) +{ + return value_create(DIRECT, NONE, p_v, NULL); +} + +struct value * value_create_direct_register(struct ttk_register *ttk_reg) +{ + struct pure_value *p_v = pure_value_create_value(0); + return value_create(DIRECT, NONE, p_v, ttk_reg); +} + +struct value * value_create_direct_indexed(struct pure_value *p_v, struct ttk_register *ttk_reg) +{ + return value_create(DIRECT, INDEXED, p_v, ttk_reg); +} + +struct value * value_create_address_mode_indexed(char addr_mode, struct pure_value *p_v, struct ttk_register *ttk_reg) +{ + return value_create(parse_addr_mode(addr_mode), INDEXED, p_v, ttk_reg); +} + +struct value * value_create_address_mode(char addr_mode, struct pure_value *p_v) +{ + return value_create(parse_addr_mode(addr_mode), NONE, p_v, NULL); +} + + + 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)); @@ -26,6 +54,11 @@ struct pure_value * pure_value_create(value_t kind, struct ttk_register *ttk_reg return v; } +struct pure_value * pure_value_create_ttk_register(struct ttk_register *ttk_reg) { return pure_value_create(REGISTER, ttk_reg, 0, NULL); } +struct pure_value * pure_value_create_value(int value) { return pure_value_create(NUMBER, NULL, value, NULL); } +struct pure_value * pure_value_create_label(struct label *l) { return pure_value_create(LABEL, NULL, 0, l); } + + addr_mode_t parse_addr_mode(char addr_mode) { switch (addr_mode) diff --git a/docs/example-file-simple.k91 b/docs/example-file-simple.k91 index 2e58fd6..088eac1 100644 --- a/docs/example-file-simple.k91 +++ b/docs/example-file-simple.k91 @@ -1,2 +1,8 @@ +; this is a test file +; +; with multiple comments + + +X DS 10 LOAD R2, @-10(R1); something STORE R3, X