cvsuser 02/12/01 03:45:14
Modified: languages/imcc imcc.l imcc.y
Log:
#18747
Revision Changes Path
1.15 +27 -2 parrot/languages/imcc/imcc.l
Index: imcc.l
===================================================================
RCS file: /cvs/public/parrot/languages/imcc/imcc.l,v
retrieving revision 1.14
retrieving revision 1.15
diff -u -w -r1.14 -r1.15
--- imcc.l 21 Oct 2002 08:50:36 -0000 1.14
+++ imcc.l 1 Dec 2002 11:45:14 -0000 1.15
@@ -19,6 +19,7 @@
#define YY_NO_UNPUT
extern long line;
extern int expect_pasm;
+extern int pasm_file;
int state;
int yyerror(char *);
%}
@@ -28,9 +29,11 @@
LETTER [a-zA-Z_]
DIGIT [0-9]
HEX 0x[0-9A-Fa-f]+
+BIN 0b[01]+
DOT [.]
-LETTERDIGIT [a-zA-Z0-9_]
SIGN [-+]
+FLOATNUM {SIGN}?{DIGIT}+{DOT}{DIGIT}*([eE]{SIGN}?{DIGIT}+)?
+LETTERDIGIT [a-zA-Z0-9_]
STRINGCONSTANT \"(\\.|[^"\n]*)*["\n]
CHARCONSTANT \'[^'\n]*\'
RANKSPEC \[[,]*\]
@@ -43,6 +46,10 @@
expect_pasm = 2;
BEGIN(emit);
}
+ if (pasm_file && YYSTATE != emit) {
+ BEGIN(emit);
+ return pasm_file == 1 ? EMIT : 0;
+ }
<INITIAL,emit>{EOL} {
if (expect_pasm == 2)
@@ -152,7 +159,7 @@
return(is_op(yylval.s) ? PARROT_OP : IDENTIFIER);
}
-<emit,INITIAL>{SIGN}?{DIGIT}+"."{DIGIT}+ {
+<emit,INITIAL>{FLOATNUM} {
yylval.s = str_dup(yytext);
return(FLOATC);
}
@@ -165,10 +172,18 @@
yylval.s = str_dup(yytext);
return(INTC);
}
+<emit>{BIN} {
+ yylval.s = str_dup(yytext);
+ return(INTC);
+ }
<emit,INITIAL>{STRINGCONSTANT} {
yylval.s = str_dup(yytext); /* XXX delete quotes, -> emit, pbc */
return(STRINGC);
}
+<emit>{CHARCONSTANT} {
+ yylval.s = str_dup(yytext);
+ return(STRINGC);
+ }
<emit,INITIAL>\$I[0-9]+ {
yylval.s = str_dup(yytext);
@@ -195,6 +210,16 @@
return yytext[0];
}
+<emit><<EOF>> {
+ BEGIN (INITIAL);
+ if (pasm_file) {
+ pasm_file = 2;
+ return EOM;
+ }
+ return 0;
+ }
+
+<<EOF>> yyterminate();
%%
#ifdef yywrap
1.27 +121 -11 parrot/languages/imcc/imcc.y
Index: imcc.y
===================================================================
RCS file: /cvs/public/parrot/languages/imcc/imcc.y,v
retrieving revision 1.26
retrieving revision 1.27
diff -u -w -r1.26 -r1.27
--- imcc.y 21 Oct 2002 08:50:36 -0000 1.26
+++ imcc.y 1 Dec 2002 11:45:14 -0000 1.27
@@ -27,6 +27,7 @@
int yylex();
extern char yytext[];
int expect_pasm;
+int pasm_file = 0;
/*
* Choosing instructions for Parrot is pretty easy since
@@ -240,6 +241,100 @@
}
+static Instruction *
+multi_keyed(char *name, SymReg ** regs, int nr, int emit)
+{
+ int i, keys, kv, n;
+ char buf[16];
+ static int p = 0;
+ SymReg *preg[IMCC_MAX_REGS]; /* px,py,pz */
+ SymReg *nreg[IMCC_MAX_REGS];
+ Instruction * ins, *last;
+
+ /* count keys in keyvec */
+ kv = keyvec;
+ for (i = keys = 0; i < nr; i++, kv >>= 1)
+ if (kv & 1)
+ keys++;
+ if (keys <= 1)
+ return 0;
+ /* XXX what to do, if we don't emit instruction? */
+ assert(emit);
+ /* OP _p_k _p_k_p_k =>
+ * set py, p_k
+ * set pz, p_k
+ * new px, .PerlUndef
+ * OP px, py, pz
+ * set _p_k_px
+ */
+
+ kv = keyvec;
+ for (i = n = 0; i < nr; i++, kv >>= 1, n++) {
+ if (kv & 1) {
+ fataly(EX_SOFTWARE, "multi_keyed", line,"illegal key operand\n");
+ }
+ /* make a new P symbol */
+ while (1) {
+ sprintf(buf, "$P%d", ++p);
+ if (get_sym(buf) == 0)
+ break;
+ }
+ preg[n] = mk_symreg(buf, 'P');
+ kv >>= 1;
+ if (kv & 1) {
+ /* we have a keyed operand */
+ if (regs[i]->set != 'P') {
+ fataly(EX_SOFTWARE, "multi_keyed", line,"not an aggregate\n");
+ }
+ nargs = 3;
+ /* don't emit LHS yet */
+ if (i == 0) {
+ keyvec = 1 << 1;
+ nreg[0] = regs[i];
+ nreg[1] = regs[i+1];
+ nreg[2] = preg[n];
+ /* set p_k px */
+ ins = iANY(str_dup("set"), 0, nreg, 0);
+ }
+ else {
+ keyvec = 1 << 2;
+ nreg[0] = preg[n];
+ nreg[1] = regs[i];
+ nreg[2] = regs[i+1];
+ /* set py|z p_k */
+ iANY(str_dup("set"), 0, nreg, 1);
+ }
+ i++;
+ }
+ /* non keyed */
+ else {
+ nargs = 2;
+ keyvec = 0;
+ if (i == 0) {
+ nreg[0] = regs[i];
+ nreg[1] = preg[n];
+ /* set n, px */
+ ins = iANY(str_dup("set"), 0, nreg, 0);
+ }
+ else {
+ nreg[0] = preg[n];
+ nreg[1] = regs[i];
+ /* set px, n */
+ iANY(str_dup("set"), 0, nreg, 1);
+ }
+ }
+ }
+ /* make a new undef */
+ iNEW(preg[0], str_dup("PerlUndef"), 1);
+ /* emit the operand */
+ nargs = 3;
+ keyvec = 0;
+ iANY(name, 0, preg, 1);
+ /* emit the LHS op */
+ emitb(ins);
+ return ins;
+}
+
Instruction * iANY(char * name, char *fmt, SymReg **regs, int emit) {
char fullname[64];
int i;
@@ -247,6 +342,11 @@
int op;
Instruction * ins;
+#if 1
+ ins = multi_keyed(name, regs, nargs, emit);
+ if (ins)
+ return ins;
+#endif
op_fullname(fullname, name, regs, nargs);
op = interpreter->op_lib->op_code(fullname, 1);
if (op >= 0) {
@@ -332,7 +432,6 @@
fataly(EX_SOFTWARE, "iANY", line,"op not found '%s' (%s<%d>)\n",
fullname, name, nargs);
}
- clear_state();
return ins;
}
@@ -384,7 +483,8 @@
pasmline: labels pasm_inst '\n' { $$ = 0; }
;
-pasm_inst: PARROT_OP pasm_args { $$ = iANY($1,0,regs,1); free($1); }
+pasm_inst: {clear_state();}
+ PARROT_OP pasm_args { $$ = iANY($2,0,regs,1); free($2); }
| /* none */ { $$ = 0;}
;
@@ -427,7 +527,8 @@
| statements statement
;
-statement: instruction
+statement: {clear_state(); }
+ instruction
;
labels: /* none */ { $$ = NULL; }
@@ -681,7 +782,7 @@
fgetc(stdin);
break;
case 'h':
- usage(stdin);
+ usage(stdout);
break;
case 'V':
version();
@@ -756,11 +857,17 @@
}
else if (!strcmp(sourcefile, "-"))
yyin = stdin;
- else
+ else {
+ char *ext;
if(!(yyin = fopen(sourcefile, "r"))) {
fatal(EX_IOERR, "main", "Error reading source file %s.\n",
sourcefile);
}
+ ext = strrchr(sourcefile, '.');
+ if (ext && strcmp (ext, ".pasm") == 0) {
+ pasm_file = 1;
+ }
+ }
if (!output)
output = str_dup(pbc ? "a.pbc" : "a.pasm");
@@ -797,8 +904,11 @@
if (!packed)
fatal(1, "main", "Out of mem\n");
PackFile_pack(interpreter->code, packed);
- if ((fp = fopen(output, "wb")) == 0)
+ if (strcmp (output, "-") == 0)
+ fp = stdout;
+ else if ((fp = fopen(output, "wb")) == 0)
fatal(1, "main", "Couldn't open %s\n", output);
+
if ((1 != fwrite(packed, size, 1, fp)) )
fatal(1, "main", "Couldn't write %s\n", output);
fclose(fp);
@@ -811,8 +921,8 @@
info(1, "Running...\n");
Parrot_runcode(interpreter, argc, argv);
/* XXX no return value :-( */
- Parrot_destroy(interpreter);
}
+ Parrot_destroy(interpreter);
free(output);
return 0;