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>