mirror of
https://github.com/sigmasternchen/macrofuck
synced 2025-03-15 15:18:56 +00:00
feat: Add to_str macro
This commit is contained in:
parent
bc600d11a2
commit
7fb2f387de
9 changed files with 159 additions and 11 deletions
6
Makefile
6
Makefile
|
@ -2,14 +2,16 @@ CC = gcc
|
|||
CFLAGS = -std=c11 -Wall -Wpedantic -g -I./src -I./gen
|
||||
LD = gcc
|
||||
LDFLAGS =
|
||||
YACC = yacc
|
||||
YACC = bison
|
||||
YFLAGS = -d
|
||||
LEX = lex
|
||||
LEXFLAGS =
|
||||
|
||||
|
||||
PLUGINS = obj/macros/numbers.o
|
||||
OBJS = obj/lex.yy.o obj/y.tab.o obj/codegen.o obj/error.o \
|
||||
obj/ast.o obj/alloc.o obj/dict.o obj/list.o obj/band.o \
|
||||
obj/plugins.o obj/main.o
|
||||
obj/plugins.o $(PLUGINS) obj/main.o
|
||||
DEPS = $(OBJS:%.o=%.d)
|
||||
|
||||
-include $(DEPS)
|
||||
|
|
13
src/ast.c
13
src/ast.c
|
@ -45,7 +45,7 @@ struct statement* declaration_statement_new(char* id, struct expression* expr) {
|
|||
return stat;
|
||||
}
|
||||
|
||||
struct statement* macro_expression(struct expression* expr) {
|
||||
struct statement* macro_statement_new(struct expression* expr) {
|
||||
_new(stat, statement);
|
||||
stat->kind = MACRO_STATEMENT;
|
||||
stat->macro = (struct macro_statement) {
|
||||
|
@ -65,6 +65,17 @@ struct expression* literal_expression_char_new(char c) {
|
|||
return expr;
|
||||
}
|
||||
|
||||
struct expression* literal_expression_num_new(long long i) {
|
||||
_new(expr, expression);
|
||||
expr->kind = LITERAL;
|
||||
expr->type = INTEGER;
|
||||
expr->literal = (struct literal_expression) {
|
||||
.kind = NUMBER_LITERAL,
|
||||
.number = i,
|
||||
};
|
||||
return expr;
|
||||
}
|
||||
|
||||
struct expression* literal_expression_str_new(char* s) {
|
||||
_new(expr, expression);
|
||||
expr->kind = LITERAL;
|
||||
|
|
|
@ -88,7 +88,7 @@ void program_add_statement(struct program*, struct statement*);
|
|||
|
||||
struct statement* print_statement_new(struct expression*);
|
||||
struct statement* declaration_statement_new(char*, struct expression*);
|
||||
struct statement* macro_expression(struct expression*);
|
||||
struct statement* macro_statement_new(struct expression*);
|
||||
|
||||
struct expression* literal_expression_char_new(char);
|
||||
struct expression* literal_expression_str_new(char*);
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "ast.h"
|
||||
#include "band.h"
|
||||
#include "error.h"
|
||||
#include "plugins.h"
|
||||
|
||||
|
||||
void _move_to(FILE* out, band_t* band, size_t target) {
|
||||
|
@ -83,8 +84,8 @@ region_t* codegen_variable_expr(FILE* _, band_t* band, struct variable_expressio
|
|||
}
|
||||
|
||||
region_t* codegen_macro_expr(FILE* out, band_t* band, struct macro_expression expr) {
|
||||
// TODO
|
||||
return band_allocate_tmp(band, 1);
|
||||
macro_t macro = find_macro(expr.id);
|
||||
return macro(out, band, expr.argument);
|
||||
}
|
||||
|
||||
region_t* codegen_expr(FILE* out, band_t* band, struct expression* expr) {
|
||||
|
|
121
src/macros/numbers.c
Normal file
121
src/macros/numbers.c
Normal file
|
@ -0,0 +1,121 @@
|
|||
#include "../band.h"
|
||||
#include "../error.h"
|
||||
#include "../codegen.h"
|
||||
|
||||
extern region_t* to_str(FILE* out, band_t* band, const char* _arg) {
|
||||
region_t* arg = band_region_for_var(band, _arg);
|
||||
if (!arg) {
|
||||
panic("argument has to be a variable");
|
||||
}
|
||||
|
||||
region_t* str = band_allocate_tmp(band, 3);
|
||||
for (size_t i = 0; i < str->size; i++) {
|
||||
move_to(str->start + i); reset();
|
||||
}
|
||||
|
||||
region_t* copy = band_allocate_tmp(band, 1);
|
||||
move_to(copy->start); reset();
|
||||
|
||||
region_t* ten = band_allocate_tmp(band, 1);
|
||||
move_to(ten->start); reset(); add(10);
|
||||
|
||||
region_t* tmp = band_allocate_tmp(band, 1);
|
||||
move_to(tmp->start); reset();
|
||||
region_t* tmp2 = band_allocate_tmp(band, 1);
|
||||
move_to(tmp2->start); reset();
|
||||
region_t* tmp3 = band_allocate_tmp(band, 1);
|
||||
|
||||
move_to(arg->start);
|
||||
loop({
|
||||
dec();
|
||||
move_to(tmp->start); inc();
|
||||
move_to(copy->start); inc();
|
||||
move_to(str->start + 2); inc();
|
||||
move_to(str->start + 1); reset();
|
||||
move_to(str->start + 0); reset();
|
||||
move_to(ten->start); dec();
|
||||
loop({
|
||||
dec();
|
||||
move_to(str->start + 0); inc();
|
||||
move_to(str->start + 1); inc();
|
||||
move_to(ten->start);
|
||||
});
|
||||
move_to(str->start + 1);
|
||||
loop({
|
||||
move_to(tmp->start); reset();
|
||||
move_to(str->start + 1); reset();
|
||||
});
|
||||
move_to(str->start + 0);
|
||||
loop({
|
||||
dec();
|
||||
move_to(ten->start); inc();
|
||||
move_to(str->start + 0);
|
||||
});
|
||||
move_to(tmp->start);
|
||||
loop({
|
||||
move_to(tmp2->start); inc();
|
||||
move_to(str->start + 2); reset();
|
||||
move_to(ten->start); add(10);
|
||||
move_to(tmp->start); reset();
|
||||
});
|
||||
|
||||
move_to(arg->start);
|
||||
});
|
||||
|
||||
move_to(copy->start);
|
||||
loop({
|
||||
dec();
|
||||
move_to(arg->start); inc();
|
||||
move_to(copy->start);
|
||||
});
|
||||
|
||||
move_to(ten->start); reset(); add(10);
|
||||
|
||||
move_to(tmp2->start);
|
||||
loop({
|
||||
dec();
|
||||
move_to(tmp->start); reset(); inc();
|
||||
move_to(str->start + 1); inc();
|
||||
move_to(copy->start); reset();
|
||||
move_to(tmp3->start); reset();
|
||||
move_to(ten->start); dec();
|
||||
loop({
|
||||
dec();
|
||||
move_to(copy->start); inc();
|
||||
move_to(tmp3->start); inc();
|
||||
move_to(ten->start);
|
||||
});
|
||||
move_to(tmp3->start);
|
||||
loop({
|
||||
move_to(tmp->start); reset();
|
||||
move_to(tmp3->start); reset();
|
||||
});
|
||||
move_to(copy->start);
|
||||
loop({
|
||||
dec();
|
||||
move_to(ten->start); inc();
|
||||
move_to(copy->start);
|
||||
});
|
||||
|
||||
move_to(tmp->start);
|
||||
loop({
|
||||
move_to(ten->start); add(10);
|
||||
move_to(str->start + 0); inc();
|
||||
move_to(str->start + 1); reset();
|
||||
move_to(tmp->start); reset();
|
||||
});
|
||||
|
||||
move_to(tmp2->start);
|
||||
});
|
||||
|
||||
for (size_t i = 0; i < str->size; i++) {
|
||||
move_to(str->start + i); add('0');
|
||||
}
|
||||
|
||||
band_region_free(band, tmp3);
|
||||
band_region_free(band, tmp2);
|
||||
band_region_free(band, tmp);
|
||||
band_region_free(band, ten);
|
||||
|
||||
return str;
|
||||
}
|
|
@ -11,6 +11,7 @@
|
|||
|
||||
extern FILE* yyin;
|
||||
extern int yyparse(void);
|
||||
extern int yydebug;
|
||||
|
||||
struct program* program;
|
||||
|
||||
|
@ -19,6 +20,8 @@ void help(void) {
|
|||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
//yydebug = 1;
|
||||
|
||||
FILE* input;
|
||||
FILE* output = NULL;
|
||||
|
||||
|
|
14
src/parser.y
14
src/parser.y
|
@ -1,5 +1,7 @@
|
|||
%{
|
||||
|
||||
#define YYDEBUG 1
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdbool.h>
|
||||
|
@ -16,6 +18,8 @@ extern struct program* program;
|
|||
|
||||
%}
|
||||
|
||||
%verbose
|
||||
|
||||
%union {
|
||||
struct program* program;
|
||||
struct statement* statement;
|
||||
|
@ -34,10 +38,10 @@ extern struct program* program;
|
|||
%token <ch> CHAR
|
||||
%token <str> STR
|
||||
%token <id> ID
|
||||
%token <str> MACRO_CONTENT
|
||||
|
||||
%token SEMICOLON
|
||||
%token EQUALS
|
||||
%token MACRO_CONTENT
|
||||
|
||||
%token VAR
|
||||
%token PRINT
|
||||
|
@ -82,18 +86,18 @@ definition: VAR ID EQUALS expr
|
|||
|
||||
macrostat: macroexpr
|
||||
{
|
||||
$$ = NULL;
|
||||
$$ = macro_statement_new($1);
|
||||
}
|
||||
;
|
||||
|
||||
expr: literal
|
||||
| variable
|
||||
| macroexpr
|
||||
;
|
||||
|
||||
literal: NUM
|
||||
{
|
||||
yyerror(ERROR("number literals not yet supported"));
|
||||
YYERROR;
|
||||
$$ = literal_expression_num_new($1);
|
||||
}
|
||||
| CHAR
|
||||
{
|
||||
|
@ -112,7 +116,7 @@ variable: ID
|
|||
|
||||
macroexpr: ID MACRO_CONTENT
|
||||
{
|
||||
$$ = NULL;
|
||||
$$ = macro_expression_new($1, $2);
|
||||
}
|
||||
;
|
||||
|
||||
|
|
3
test/cases/007-print-to_str-macro.in
Normal file
3
test/cases/007-print-to_str-macro.in
Normal file
|
@ -0,0 +1,3 @@
|
|||
var tmp = 128;
|
||||
print to_str!(tmp);
|
||||
print "\n";
|
3
test/cases/007-print-to_str-macro.out
Normal file
3
test/cases/007-print-to_str-macro.out
Normal file
|
@ -0,0 +1,3 @@
|
|||
[-]++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
>[-]>[-]>[-]>[-]>[-]++++++++++>[-]>[-]<<<<<<<[->>>>>>+<<+<+<[-]<[-]>>>>-[-<<<<+>+>>>]<<<[>>>>[-]<<<<[-]]<[->>>>+<<<<]>>>>>[>+<<<<[-]>>++++++++++>[-]]<<<<<<]>>>>[-<<<<+>>>>]>[-]++++++++++>>[-<[-]+<<<<+>>[-]>>>>[-]<<<-[-<+>>>>+<<<]>>>[<<[-]>>[-]]<<<<[->+<]>>[<++++++++++<<<<+>[-]>>>>[-]]>]<<<<<<++++++++++++++++++++++++++++++++++++++++++++++++>++++++++++++++++++++++++++++++++++++++++++++++++>++++++++++++++++++++++++++++++++++++++++++++++++<<.>.>.
|
||||
<<[-]++++++++++.
|
Loading…
Reference in a new issue