mirror of
https://github.com/sigmasternchen/macrofuck
synced 2025-03-15 07:08:56 +00:00
feat: Change print syntax to builtin
This commit is contained in:
parent
8a645a635d
commit
0461a3d2ea
30 changed files with 172 additions and 172 deletions
|
@ -10,7 +10,8 @@ MAKE = make
|
|||
|
||||
|
||||
PLUGINS =
|
||||
BUILTINS = obj/builtins/builtins.o obj/builtins/numbers.o
|
||||
BUILTINS = obj/builtins/builtins.o obj/builtins/numbers.o \
|
||||
obj/builtins/print.o
|
||||
OBJS = obj/lex.yy.o obj/y.tab.o obj/codegen.o obj/ast.o obj/band.o \
|
||||
obj/plugins.o obj/scope.o $(PLUGINS) $(BUILTINS) obj/main.o
|
||||
DEPS = $(OBJS:%.o=%.d)
|
||||
|
|
|
@ -27,15 +27,6 @@ void block_add_statement(struct block* block, struct statement* statement) {
|
|||
last(block, statements) = statement;
|
||||
}
|
||||
|
||||
struct statement* print_statement_new(struct expression* expr) {
|
||||
_new(stat, statement);
|
||||
stat->kind = PRINT_STATEMENT;
|
||||
stat->print = (struct print_statement) {
|
||||
.value = expr,
|
||||
};
|
||||
return stat;
|
||||
}
|
||||
|
||||
struct statement* declaration_statement_new(struct statement* assignment) {
|
||||
if (assignment->kind != ASSIGNMENT_STATEMENT) {
|
||||
panic("argument has to be assignment");
|
||||
|
@ -57,11 +48,11 @@ struct statement* assignment_statement_new(char* id, struct expression* expr) {
|
|||
return stat;
|
||||
}
|
||||
|
||||
struct statement* macro_statement_new(struct expression* expr) {
|
||||
struct statement* expr_statement_new(struct expression* expr) {
|
||||
_new(stat, statement);
|
||||
stat->kind = MACRO_STATEMENT;
|
||||
stat->macro = (struct macro_statement) {
|
||||
.expr = expr,
|
||||
stat->kind = EXPR_STATEMENT;
|
||||
stat->expr = (struct expr_statement) {
|
||||
.expr = expr,
|
||||
};
|
||||
return stat;
|
||||
}
|
||||
|
|
|
@ -25,10 +25,9 @@ enum expression_type {
|
|||
};
|
||||
|
||||
enum statement_kind {
|
||||
PRINT_STATEMENT,
|
||||
DECL_STATEMENT,
|
||||
ASSIGNMENT_STATEMENT,
|
||||
MACRO_STATEMENT,
|
||||
EXPR_STATEMENT,
|
||||
IF_STATEMENT,
|
||||
WHILE_STATEMENT,
|
||||
};
|
||||
|
@ -88,19 +87,11 @@ struct expression {
|
|||
};
|
||||
};
|
||||
|
||||
struct print_statement {
|
||||
struct expression* value;
|
||||
};
|
||||
|
||||
struct assignment_statement {
|
||||
char* id;
|
||||
struct expression* value;
|
||||
};
|
||||
|
||||
struct macro_statement {
|
||||
struct expression* expr;
|
||||
};
|
||||
|
||||
struct if_statement {
|
||||
struct expression* condition;
|
||||
struct block* if_block;
|
||||
|
@ -112,12 +103,15 @@ struct while_statement {
|
|||
struct block* block;
|
||||
};
|
||||
|
||||
struct expr_statement {
|
||||
struct expression* expr;
|
||||
};
|
||||
|
||||
struct statement {
|
||||
enum statement_kind kind;
|
||||
union {
|
||||
struct print_statement print;
|
||||
struct assignment_statement assignment;
|
||||
struct macro_statement macro;
|
||||
struct expr_statement expr;
|
||||
struct if_statement if_else;
|
||||
struct while_statement while_loop;
|
||||
};
|
||||
|
@ -131,10 +125,9 @@ struct block {
|
|||
struct block* block_new(void);
|
||||
void block_add_statement(struct block*, struct statement*);
|
||||
|
||||
struct statement* print_statement_new(struct expression*);
|
||||
struct statement* declaration_statement_new(struct statement*);
|
||||
struct statement* assignment_statement_new(char*, struct expression*);
|
||||
struct statement* macro_statement_new(struct expression*);
|
||||
struct statement* expr_statement_new(struct expression*);
|
||||
struct statement* if_statement_new(struct expression*, struct block*, struct block*);
|
||||
struct statement* while_statement_new(struct expression*, struct block*);
|
||||
|
||||
|
|
|
@ -5,12 +5,14 @@
|
|||
#define decl(n) region_t* n(FILE*, scope_t*, size_t, region_t**)
|
||||
|
||||
decl(to_str);
|
||||
decl(print);
|
||||
|
||||
static struct builtin_list_item {
|
||||
const char* name;
|
||||
builtin_t function;
|
||||
} builtins[] = {
|
||||
{"to_str", to_str },
|
||||
{"to_str", to_str},
|
||||
{"print", print},
|
||||
};
|
||||
|
||||
builtin_t find_builtin(const char* name) {
|
||||
|
|
38
compiler/src/builtins/print.c
Normal file
38
compiler/src/builtins/print.c
Normal file
|
@ -0,0 +1,38 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include <error.h>
|
||||
|
||||
#include "../scope.h"
|
||||
#include "../codegen.h"
|
||||
|
||||
static size_t print_region(FILE* out, scope_t* scope, region_t* region) {
|
||||
move_to(region);
|
||||
|
||||
output();
|
||||
|
||||
size_t i = 1;
|
||||
for (; i < region->size; i++) {
|
||||
next();
|
||||
output();
|
||||
}
|
||||
scope->band->position += region->size - 1;
|
||||
|
||||
if (region->is_temp)
|
||||
scope_remove(scope, region);
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
extern region_t* print(FILE* out, scope_t* scope, size_t argc, region_t** argv) {
|
||||
if (argc < 1) {
|
||||
panic("print() needs at least one argument");
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < argc; i++) {
|
||||
print_region(out, scope, argv[i]);
|
||||
}
|
||||
|
||||
// TODO: do something with this
|
||||
region_t* result = scope_add_tmp(scope, 1);
|
||||
return result;
|
||||
}
|
|
@ -526,20 +526,6 @@ region_t* codegen_expr(FILE* out, scope_t* scope, struct expression* expr) {
|
|||
panic("unknown expression kind");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void codegen_print_statement(FILE* out, scope_t* scope, struct print_statement statement) {
|
||||
region_t* region = codegen_expr(out, scope, statement.value);
|
||||
move_to(region);
|
||||
|
||||
output();
|
||||
for (size_t i = 1; i < region->size; i++) {
|
||||
next();
|
||||
output();
|
||||
}
|
||||
scope->band->position += region->size - 1;
|
||||
|
||||
region_used(scope, region);
|
||||
}
|
||||
|
||||
region_t* clone_region(FILE* out, scope_t* scope, region_t* original) {
|
||||
|
@ -610,13 +596,6 @@ void codegen_decl_statement(FILE* out, scope_t* scope, struct assignment_stateme
|
|||
scope_existing(scope, region, statement.id);
|
||||
}
|
||||
|
||||
void codegen_macro_statement(FILE* out, scope_t* scope, struct macro_statement statement) {
|
||||
region_t* region = codegen_expr(out, scope, statement.expr);
|
||||
if (region->is_temp) {
|
||||
scope_remove(scope, region);
|
||||
}
|
||||
}
|
||||
|
||||
void codegen_block(FILE*, scope_t*, struct block*);
|
||||
|
||||
void codegen_if_statement(FILE* out, scope_t* scope, struct if_statement statement) {
|
||||
|
@ -680,19 +659,24 @@ void codegen_while_statement(FILE* out, scope_t* scope, struct while_statement s
|
|||
scope_remove(scope, condition);
|
||||
}
|
||||
|
||||
|
||||
void codegen_expr_statement(FILE* out, scope_t* scope, struct expr_statement statement) {
|
||||
region_t* region = codegen_expr(out, scope, statement.expr);
|
||||
if (region->is_temp) {
|
||||
scope_remove(scope, region);
|
||||
}
|
||||
}
|
||||
|
||||
void codegen_statement(FILE* out, scope_t* scope, struct statement* statement) {
|
||||
switch(statement->kind) {
|
||||
case PRINT_STATEMENT:
|
||||
codegen_print_statement(out, scope, statement->print);
|
||||
break;
|
||||
case DECL_STATEMENT:
|
||||
codegen_decl_statement(out, scope, statement->assignment);
|
||||
break;
|
||||
case ASSIGNMENT_STATEMENT:
|
||||
codegen_assignment_statement(out, scope, statement->assignment);
|
||||
break;
|
||||
case MACRO_STATEMENT:
|
||||
codegen_macro_statement(out, scope, statement->macro);
|
||||
case EXPR_STATEMENT:
|
||||
codegen_expr_statement(out, scope, statement->expr);
|
||||
break;
|
||||
case IF_STATEMENT:
|
||||
codegen_if_statement(out, scope, statement->if_else);
|
||||
|
|
|
@ -65,7 +65,6 @@ strbuf_t strbuf = NULL;
|
|||
<STRING>\\. { lex_panic("invalid escape: %s\n", yytext); }
|
||||
<STRING>\n { lex_panic("newline in string\n"); }
|
||||
|
||||
<INITIAL>{print} { return PRINT; }
|
||||
<INITIAL>{var} { return VAR; }
|
||||
<INITIAL>{if} { return IF; }
|
||||
<INITIAL>{else} { return ELSE; }
|
||||
|
|
|
@ -33,7 +33,7 @@ extern struct block* program;
|
|||
}
|
||||
|
||||
%type <block> stats optelse block
|
||||
%type <statement> stat print definition assignment macrostat if while
|
||||
%type <statement> stat definition assignment exprstat if while
|
||||
%type <expr> expr literal variable macroexpr builtincall calcexpr argumentlist
|
||||
%type <op> op
|
||||
|
||||
|
@ -63,7 +63,6 @@ extern struct block* program;
|
|||
%token CLOSING_BRACES
|
||||
|
||||
%token VAR
|
||||
%token PRINT
|
||||
%token IF
|
||||
%token ELSE
|
||||
%token WHILE
|
||||
|
@ -89,20 +88,13 @@ stats: /* empty */
|
|||
}
|
||||
;
|
||||
|
||||
stat: print SEMICOLON
|
||||
| definition SEMICOLON
|
||||
stat: definition SEMICOLON
|
||||
| assignment SEMICOLON
|
||||
| macrostat SEMICOLON
|
||||
| exprstat SEMICOLON
|
||||
| if
|
||||
| while
|
||||
;
|
||||
|
||||
print: PRINT expr
|
||||
{
|
||||
$$ = print_statement_new($2);
|
||||
}
|
||||
;
|
||||
|
||||
definition: VAR assignment
|
||||
{
|
||||
$$ = declaration_statement_new($2);
|
||||
|
@ -144,10 +136,10 @@ block: OPENING_BRACES stats CLOSING_BRACES
|
|||
}
|
||||
;
|
||||
|
||||
macrostat: macroexpr
|
||||
{
|
||||
$$ = macro_statement_new($1);
|
||||
}
|
||||
exprstat: expr
|
||||
{
|
||||
$$ = expr_statement_new($1);
|
||||
}
|
||||
;
|
||||
|
||||
expr: literal
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
print 'A';
|
||||
print('A');
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
print "Hello, World!\n";
|
||||
print("Hello, World!\n");
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
print " bottle of beer on the wall.\n";
|
||||
print " bottle of beer.\n";
|
||||
print "Take on down, pass it around.\n";
|
||||
print " bottles of beer on the wall.\n";
|
||||
print " bottles of beer.\n";
|
||||
print "Take on down, pass it around.\n";
|
||||
print " bottle of beer on the wall.\n";
|
||||
print " bottles of beer on the wall.\n";
|
||||
print "\n";
|
||||
print "No more bottles of beer on the wall,\n";
|
||||
print "no more bottles of beer.\n";
|
||||
print "We've taken them down\n";
|
||||
print "and passed them around;\n";
|
||||
print "now we're drunk and passed out!\n";
|
||||
print(" bottle of beer on the wall.\n");
|
||||
print(" bottle of beer.\n");
|
||||
print("Take on down, pass it around.\n");
|
||||
print(" bottles of beer on the wall.\n");
|
||||
print(" bottles of beer.\n");
|
||||
print("Take on down, pass it around.\n");
|
||||
print(" bottle of beer on the wall.\n");
|
||||
print(" bottles of beer on the wall.\n");
|
||||
print("\n");
|
||||
print("No more bottles of beer on the wall,\n");
|
||||
print("no more bottles of beer.\n");
|
||||
print("We've taken them down\n");
|
||||
print("and passed them around;\n");
|
||||
print("now we're drunk and passed out!\n");
|
|
@ -1,2 +1,2 @@
|
|||
print "Hello, ";
|
||||
print "World!\n";
|
||||
print("Hello, ");
|
||||
print("World!\n");
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
var tmp = "Hello, World!\n";
|
||||
print tmp;
|
||||
print(tmp);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
var foo = "foo";
|
||||
var bar = "bar\n";
|
||||
print foo;
|
||||
print bar;
|
||||
print(foo);
|
||||
print(bar);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
var foo = "foobar\n";
|
||||
var bar = foo;
|
||||
print foo;
|
||||
print bar;
|
||||
print(foo);
|
||||
print(bar);
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
var tmp = 128;
|
||||
print to_str(tmp);
|
||||
print "\n";
|
||||
print(to_str(tmp));
|
||||
print("\n");
|
||||
|
|
|
@ -3,5 +3,5 @@ var b = 10;
|
|||
var c = 10;
|
||||
var d = 18;
|
||||
var r = (((((a + 2) * b) + c) - 0x14) - d);
|
||||
print to_str(r);
|
||||
print "\n";
|
||||
print(to_str(r));
|
||||
print("\n");
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
var a = 1;
|
||||
|
||||
/* this print statement seems to somehow change the value of a */
|
||||
print "a\n";
|
||||
/* this print(statement seems to somehow change the value of a */
|
||||
print("a\n");
|
||||
|
||||
var b = (a - 1);
|
||||
print to_str(b);
|
||||
print "\n";
|
||||
print(to_str(b));
|
||||
print("\n");
|
|
@ -1,5 +1,5 @@
|
|||
var a = 128;
|
||||
var b = 16;
|
||||
var c = (a / b);
|
||||
print to_str(c);
|
||||
print "\n";
|
||||
print(to_str(c));
|
||||
print("\n");
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
var a = 255;
|
||||
var b = 99;
|
||||
var c = (a % b);
|
||||
print to_str(c);
|
||||
print "\n";
|
||||
print(to_str(c));
|
||||
print("\n");
|
|
@ -1,19 +1,19 @@
|
|||
if 1 {
|
||||
print "foo\n";
|
||||
print("foo\n");
|
||||
} else {
|
||||
print "bar\n";
|
||||
print("bar\n");
|
||||
}
|
||||
|
||||
if 0 {
|
||||
print "foobar\n";
|
||||
print("foobar\n");
|
||||
} else {
|
||||
print "baz\n";
|
||||
print("baz\n");
|
||||
}
|
||||
|
||||
if 1 {
|
||||
print "no else\n";
|
||||
print("no else\n");
|
||||
}
|
||||
|
||||
if 0 {
|
||||
print "this should not be printed\n";
|
||||
print("this should not be printed\n");
|
||||
}
|
|
@ -1,14 +1,14 @@
|
|||
var a = 1;
|
||||
|
||||
if a {
|
||||
print "a\n";
|
||||
print("a\n");
|
||||
|
||||
if (a + 1) {
|
||||
print "b\n";
|
||||
print("b\n");
|
||||
}
|
||||
|
||||
var b = (a - 1);
|
||||
if b {
|
||||
print "c\n";
|
||||
print("c\n");
|
||||
}
|
||||
}
|
|
@ -1,40 +1,40 @@
|
|||
var a = 5;
|
||||
var b = 3;
|
||||
|
||||
print to_str(a);
|
||||
print "\n";
|
||||
print to_str(b);
|
||||
print "\n";
|
||||
print(to_str(a));
|
||||
print("\n");
|
||||
print(to_str(b));
|
||||
print("\n");
|
||||
|
||||
a = (a * b);
|
||||
b = (a / b);
|
||||
|
||||
print to_str(a);
|
||||
print "\n";
|
||||
print to_str(b);
|
||||
print "\n";
|
||||
print(to_str(a));
|
||||
print("\n");
|
||||
print(to_str(b));
|
||||
print("\n");
|
||||
|
||||
a = (a + b);
|
||||
b = a;
|
||||
|
||||
print to_str(a);
|
||||
print "\n";
|
||||
print to_str(b);
|
||||
print "\n";
|
||||
print(to_str(a));
|
||||
print("\n");
|
||||
print(to_str(b));
|
||||
print("\n");
|
||||
|
||||
a = a;
|
||||
b = (b / 2);
|
||||
|
||||
print to_str(a);
|
||||
print "\n";
|
||||
print to_str(b);
|
||||
print "\n";
|
||||
print(to_str(a));
|
||||
print("\n");
|
||||
print(to_str(b));
|
||||
print("\n");
|
||||
|
||||
a = 0;
|
||||
b = 1;
|
||||
|
||||
print to_str(a);
|
||||
print "\n";
|
||||
print to_str(b);
|
||||
print "\n";
|
||||
print(to_str(a));
|
||||
print("\n");
|
||||
print(to_str(b));
|
||||
print("\n");
|
||||
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
var a = 1;
|
||||
print to_str(a);
|
||||
print "\n";
|
||||
print(to_str(a));
|
||||
print("\n");
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
var i = 10;
|
||||
|
||||
while i {
|
||||
print to_str(i);
|
||||
print "\n";
|
||||
print(to_str(i));
|
||||
print("\n");
|
||||
i = (i - 1);
|
||||
}
|
|
@ -2,17 +2,17 @@ var a = 123;
|
|||
var b = 124;
|
||||
|
||||
if (a == b) {
|
||||
print "no\n";
|
||||
print("no\n");
|
||||
}
|
||||
|
||||
if (a != b) {
|
||||
print "yes\n";
|
||||
print("yes\n");
|
||||
}
|
||||
|
||||
if ((a + 1) == b) {
|
||||
print "yes\n";
|
||||
print("yes\n");
|
||||
}
|
||||
|
||||
if ((a + 1) != b) {
|
||||
print "no\n";
|
||||
print("no\n");
|
||||
}
|
|
@ -4,34 +4,34 @@ while bottles {
|
|||
var bottles_string = to_str(bottles);
|
||||
|
||||
if (bottles == 1) {
|
||||
print bottles_string;
|
||||
print " bottle of beer on the wall.\n";
|
||||
print bottles_string;
|
||||
print " bottle of beer.\n";
|
||||
print "Take on down, pass it around.\n";
|
||||
print(bottles_string);
|
||||
print(" bottle of beer on the wall.\n");
|
||||
print(bottles_string);
|
||||
print(" bottle of beer.\n");
|
||||
print("Take on down, pass it around.\n");
|
||||
} else {
|
||||
print bottles_string;
|
||||
print " bottles of beer on the wall.\n";
|
||||
print bottles_string;
|
||||
print " bottles of beer.\n";
|
||||
print "Take on down, pass it around.\n";
|
||||
print(bottles_string);
|
||||
print(" bottles of beer on the wall.\n");
|
||||
print(bottles_string);
|
||||
print(" bottles of beer.\n");
|
||||
print("Take on down, pass it around.\n");
|
||||
}
|
||||
|
||||
bottles = (bottles - 1);
|
||||
bottles_string = to_str(bottles);
|
||||
|
||||
print bottles_string;
|
||||
print(bottles_string);
|
||||
|
||||
if (bottles == 1) {
|
||||
print " bottle of beer on the wall.\n";
|
||||
print(" bottle of beer on the wall.\n");
|
||||
} else {
|
||||
print " bottles of beer on the wall.\n";
|
||||
print(" bottles of beer on the wall.\n");
|
||||
}
|
||||
print "\n";
|
||||
print("\n");
|
||||
}
|
||||
|
||||
print "No more bottles of beer on the wall,\n";
|
||||
print "no more bottles of beer.\n";
|
||||
print "We've taken them down\n";
|
||||
print "and passed them around;\n";
|
||||
print "now we're drunk and passed out!\n";
|
||||
print("No more bottles of beer on the wall,\n");
|
||||
print("no more bottles of beer.\n");
|
||||
print("We've taken them down\n");
|
||||
print("and passed them around;\n");
|
||||
print("now we're drunk and passed out!\n");
|
|
@ -1,15 +1,15 @@
|
|||
if (0 && 0) {
|
||||
print "no 00\n";
|
||||
print("no 00\n");
|
||||
}
|
||||
|
||||
if (0 && 1) {
|
||||
print "no 01\n";
|
||||
print("no 01\n");
|
||||
}
|
||||
|
||||
if (1 && 0) {
|
||||
print "no 10\n";
|
||||
print("no 10\n");
|
||||
}
|
||||
|
||||
if (1 && 1) {
|
||||
print "yes 11\n";
|
||||
print("yes 11\n");
|
||||
}
|
|
@ -1,15 +1,15 @@
|
|||
if (0 || 0) {
|
||||
print "no 00\n";
|
||||
print("no 00\n");
|
||||
}
|
||||
|
||||
if (0 || 1) {
|
||||
print "yes 01\n";
|
||||
print("yes 01\n");
|
||||
}
|
||||
|
||||
if (1 || 0) {
|
||||
print "yes 10\n";
|
||||
print("yes 10\n");
|
||||
}
|
||||
|
||||
if (1 || 1) {
|
||||
print "yes 11\n";
|
||||
print("yes 11\n");
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
if (!0) {
|
||||
print "yes 0\n";
|
||||
print("yes 0\n");
|
||||
}
|
||||
|
||||
if (!1) {
|
||||
print "no 1\n";
|
||||
print("no 1\n");
|
||||
}
|
Loading…
Reference in a new issue