feat: Change print syntax to builtin

This commit is contained in:
overflowerror 2024-04-26 16:28:39 +02:00
parent 8a645a635d
commit 0461a3d2ea
30 changed files with 172 additions and 172 deletions

View file

@ -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)

View file

@ -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;
}

View file

@ -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*);

View file

@ -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) {

View 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;
}

View file

@ -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);

View file

@ -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; }

View file

@ -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

View file

@ -1,2 +1,2 @@
print 'A';
print('A');

View file

@ -1 +1 @@
print "Hello, World!\n";
print("Hello, World!\n");

View file

@ -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");

View file

@ -1,2 +1,2 @@
print "Hello, ";
print "World!\n";
print("Hello, ");
print("World!\n");

View file

@ -1,2 +1,2 @@
var tmp = "Hello, World!\n";
print tmp;
print(tmp);

View file

@ -1,4 +1,4 @@
var foo = "foo";
var bar = "bar\n";
print foo;
print bar;
print(foo);
print(bar);

View file

@ -1,4 +1,4 @@
var foo = "foobar\n";
var bar = foo;
print foo;
print bar;
print(foo);
print(bar);

View file

@ -1,3 +1,3 @@
var tmp = 128;
print to_str(tmp);
print "\n";
print(to_str(tmp));
print("\n");

View file

@ -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");

View file

@ -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");

View file

@ -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");

View file

@ -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");

View file

@ -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");
}

View file

@ -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");
}
}

View file

@ -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");

View file

@ -1,3 +1,3 @@
var a = 1;
print to_str(a);
print "\n";
print(to_str(a));
print("\n");

View file

@ -1,7 +1,7 @@
var i = 10;
while i {
print to_str(i);
print "\n";
print(to_str(i));
print("\n");
i = (i - 1);
}

View file

@ -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");
}

View file

@ -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");

View file

@ -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");
}

View file

@ -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");
}

View file

@ -1,7 +1,7 @@
if (!0) {
print "yes 0\n";
print("yes 0\n");
}
if (!1) {
print "no 1\n";
print("no 1\n");
}