Annotation of gforth/vmgen-ex/mini.y, revision 1.1
1.1 ! anton 1: /* front-end compiler for vmgen example
! 2:
! 3: Copyright (C) 2001 Free Software Foundation, Inc.
! 4:
! 5: This file is part of Gforth.
! 6:
! 7: Gforth is free software; you can redistribute it and/or
! 8: modify it under the terms of the GNU General Public License
! 9: as published by the Free Software Foundation; either version 2
! 10: of the License, or (at your option) any later version.
! 11:
! 12: This program is distributed in the hope that it will be useful,
! 13: but WITHOUT ANY WARRANTY; without even the implied warranty of
! 14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
! 15: GNU General Public License for more details.
! 16:
! 17: You should have received a copy of the GNU General Public License
! 18: along with this program; if not, write to the Free Software
! 19: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
! 20: */
! 21:
! 22: /* I use yacc/bison here not because I think it's the best tool for
! 23: the job, but because it's widely available and popular; it's also
! 24: (barely) adequate for this job. */
! 25:
! 26: %{
! 27: #include <stdlib.h>
! 28: #include <stdio.h>
! 29: #include <string.h>
! 30: #include "mini.h"
! 31:
! 32: /* BB_BOUNDARY is needed on basic blocks without a preceding VM branch */
! 33: #define BB_BOUNDARY (last_compiled = NULL, /* suppress peephole opt */ \
! 34: block_insert(vmcodep)) /* for accurate profiling */
! 35:
! 36: Inst *vm_prim;
! 37: Inst *vmcodep;
! 38: FILE *vm_out;
! 39: int vm_debug;
! 40:
! 41: void yyerror(char *s)
! 42: {
! 43: fprintf (stderr, "%s: %d: %s\n", program_name, yylineno, s);
! 44: }
! 45:
! 46: #include "mini-gen.i"
! 47:
! 48: void gen_main_end(void)
! 49: {
! 50: gen_call(&vmcodep, func_addr("main"), func_calladjust("main"));
! 51: gen_end(&vmcodep);
! 52: BB_BOUNDARY; /* for profiling; see comment in mini.vmg:end */
! 53: }
! 54:
! 55: int locals=0;
! 56: int nonparams=0;
! 57:
! 58: int yylex();
! 59: %}
! 60:
! 61:
! 62: %token FUNC RETURN END VAR IF THEN ELSE WHILE DO BECOMES PRINT NUM IDENT
! 63:
! 64: %union {
! 65: long num;
! 66: char *string;
! 67: Inst *instp;
! 68: }
! 69:
! 70: %type <string> IDENT;
! 71: %type <num> NUM;
! 72: %type <instp> elsepart;
! 73:
! 74:
! 75: %%
! 76: program: program function
! 77: | ;
! 78:
! 79: function: FUNC IDENT { locals=0; nonparams=0; } '(' params ')'
! 80: vars { insert_func($2,vmcodep,locals,nonparams); }
! 81: stats RETURN expr ';'
! 82: END FUNC ';' { gen_return(&vmcodep, -adjust(locals)); }
! 83: ;
! 84:
! 85: params: IDENT ',' { insert_local($1); } params
! 86: | IDENT { insert_local($1); }
! 87: | ;
! 88:
! 89: vars: vars VAR IDENT ';' { insert_local($3); nonparams++; }
! 90: | ;
! 91:
! 92: stats: stats stat ';'
! 93: | ;
! 94:
! 95: stat: IF expr THEN { gen_zbranch(&vmcodep, 0); $<instp>$ = vmcodep; }
! 96: stats { $<instp>$ = $<instp>4; }
! 97: elsepart END IF { BB_BOUNDARY; $<instp>7[-1] = vmcodep; }
! 98: | WHILE { BB_BOUNDARY; $<instp>$ = vmcodep; }
! 99: expr DO { gen_zbranch(&vmcodep, 0); $<instp>$ = vmcodep; }
! 100: stats END WHILE { gen_branch(&vmcodep, $<instp>2); $<instp>5[-1] = vmcodep; }
! 101: | IDENT BECOMES expr { gen_storelocal(&vmcodep, var_offset($1)); }
! 102: | PRINT expr { gen_print(&vmcodep); }
! 103: | expr { gen_drop(&vmcodep); }
! 104: ;
! 105:
! 106: elsepart: ELSE { gen_branch(&vmcodep, 0); $<instp>$ = vmcodep; $<instp>0[-1] = vmcodep; }
! 107: stats { $$ = $<instp>2; }
! 108: | { $$ = $<instp>0; }
! 109: ;
! 110:
! 111: expr: term '+' term { gen_add(&vmcodep); }
! 112: | term '-' term { gen_sub(&vmcodep); }
! 113: | term '*' term { gen_mul(&vmcodep); }
! 114: | term '&' term { gen_and(&vmcodep); }
! 115: | term '|' term { gen_or(&vmcodep); }
! 116: | term '<' term { gen_lessthan(&vmcodep); }
! 117: | term '=' term { gen_equals(&vmcodep); }
! 118: | '!' term { gen_not(&vmcodep); }
! 119: | '-' term { gen_negate(&vmcodep); }
! 120: | term
! 121: ;
! 122:
! 123: term: '(' expr ')'
! 124: | IDENT '(' args ')' { gen_call(&vmcodep, func_addr($1), func_calladjust($1)); }
! 125: | IDENT { gen_loadlocal(&vmcodep, var_offset($1)); }
! 126: | NUM { gen_lit(&vmcodep, $1); }
! 127: ;
! 128:
! 129: /* missing: argument counting and checking against calling function */
! 130: args: expr ',' args
! 131: | expr
! 132: | ;
! 133: %%
! 134: int yywrap(void)
! 135: {
! 136: return 1;
! 137: }
! 138:
! 139: #include "lex.yy.c"
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>