#include <stdio.h>
#include <string.h>
+#include <stdlib.h>
#include "chelper.h"
#include "tree.h"
-#if 0
+#if 1
#define DDCHELP
#endif
printf("\tret\n");
}
-char *next_reg(char *s, short skip)
+char *next_reg(char *s, short skip, int params)
{
/* TODO: bessere registerwahl. das is gerade a wengal suboptimal... */
-#if 1
- char *regs[] = {"rax", "r10", "r11", "rax"};
-#else
+#define REGLEN 9
char *regs[] = {"rax", "r10", "r11", "r9", "r8", "rcx", "rdx", "rsi", "rdi"};
-#endif
+
int i=0;
if (s != (char*) NULL) {
while(i < 9) {
i++;
}
#ifdef DDCHELP
- fprintf(stderr, "next_reg(): %s\n", regs[i]);
+ fprintf(stderr, "next_reg(): %s (bei %i parameter)\n", regs[i], params);
+#endif
+ /* TODO: <= passt? */
+ if(REGLEN - params <= i) {
+ fprintf(stderr, "next_reg(): register \"%s\" in dem sich ein parameter befindet wird als temporaeres register verwendet(params: %i, i: %i)\n", regs[i], params, i);
+ /* TODO: exit hier? */
+#if 0
+ exit(4);
#endif
+ }
return regs[i];
}
* geht nicht, weil verschachtelte macros deaktiviert sind */
@end
-@autoinh s
-@autosyn node imm exprcount
+/* beschreibung der attribute
+ * s:
+ * f:
+ * gparamges:
+ * parms:
+ * node:
+ * imm:
+ * exprcount:
+ * sin:
+ * sout:
+ */
+@autoinh s gparamges
+@autosyn node imm
@attributes { char *name; } IDENT
@attributes { long val; } NUM
-@attributes { struct symbol *f; int parms; } Parms
+@attributes { struct symbol *f; int paramges; int parms; } Parms
@attributes { struct symbol *f; } FeldID Structdef Program
-@attributes { struct symbol *s; } Methoddef Statseq Exprs
-@attributes { struct symbol *s; struct treenode *node; short imm; int exprcount; } Expr Minusterm Term
-@attributes { struct symbol *s; struct treenode *node; } Lexpr Multerm Orterm Feld
-@attributes { struct symbol *sin; struct symbol *sout; struct treenode *node; } Statement
+@attributes { struct symbol *s; } Methoddef
+@attributes { struct symbol *s; int gparamges; } Statseq Exprs
+@attributes { struct symbol *s; int gparamges; struct treenode *node; short imm; int exprcount; } Expr Minusterm Term
+@attributes { struct symbol *s; int gparamges; struct treenode *node; } Lexpr Multerm Orterm Feld
+@attributes { struct symbol *sin; int gparamges; struct symbol *sout; struct treenode *node; } Statement
@traversal @postorder c
@traversal @preorder reg
@{
@i @Parms.parms@ = 1;
@i @Statseq.s@ = tab_merge(@Methoddef.s@, @Parms.f@, 0);
+ @i @Statseq.gparamges@ = @Parms.paramges@;
@gen @revorder(1) func_header(@IDENT.name@);
@}
;
IDENT Parms
@{
@i @Parms.1.parms@ = @Parms.parms@ + 1;
+ @i @Parms.0.paramges@ = @Parms.1.paramges@;
@i @Parms.0.f@ = tab_add_symbol(@Parms.1.f@, @IDENT.name@, S_PARM, 1, @Parms.parms@);
@}
|
@{
@i @Parms.f@ = tab_new();
+ @i @Parms.paramges@ = @Parms.parms@;
@}
;
statinout()
xxputsin(@Expr.s@,)
@i @Statement.node@ = new_node(O_RET, @Expr.node@, TREENULL, 0);
- @reg @Statement.node@->reg = next_reg((char *)NULL, 0); @Expr.node@->reg = @Statement.node@->reg;
+ @reg @Statement.node@->reg = next_reg((char *)NULL, 0, @Expr.gparamges@); @Expr.node@->reg = @Statement.node@->reg;
@}
;
/* TODO */
@Term.node@->reg = @Expr.node@->reg;
@Term.node@->skip = 1;
- @Minusterm.node@->reg = next_reg(@Term.node@->reg, @Expr.node@->skip);
+ @Minusterm.node@->reg = next_reg(@Term.node@->reg, @Expr.node@->skip, @Expr.gparamges@);
}
@}
@reg {
@Minusterm.1.node@->reg = @Minusterm.node@->reg;
- @Term.node@->reg = next_reg(@Minusterm.1.node@->reg, @Minusterm.node@->skip);
+ @Term.node@->reg = next_reg(@Minusterm.1.node@->reg, @Minusterm.node@->skip, @Minusterm.gparamges@);
}
@}
fprintf(stderr, "tab_add_symbol: tab(%08X), ident(%s), type(%i), check(%i), param_index(%i)\n", tab, ident, type, check, param_index);
#endif
+ if(param_index >= 6) {
+ fprintf(stderr, "eine methode hat zu viele parameter (max. 6 inkl. this erlaubt)\n");
+ exit(4);
+ }
+
if(tab_lookup(tab, ident, type) != SYMNULL) {
if(check) {
fprintf(stderr, "Identifier doppelt vorhanden: \"%s\"\n", ident);