File:  [gforth] / gforth / vmgen-ex / support.c
Revision 1.1: download - view: text, annotated - select for diffs
Sun Apr 29 11:28:24 2001 UTC (22 years, 11 months ago) by anton
Branches: MAIN
CVS tags: HEAD
added vmgen-ex

    1: /* support functions and main() 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: #include <stdlib.h>
   23: #include <stdio.h>
   24: #include <unistd.h>
   25: #include <assert.h>
   26: #include "mini.h"
   27: 
   28: void genarg_i(Inst **vmcodepp, Cell i)
   29: {
   30:   *((Cell *) *vmcodepp) = i;
   31:   (*vmcodepp)++;
   32: }
   33: 
   34: void genarg_target(Inst **vmcodepp, Inst *target)
   35: {
   36:   *((Inst **) *vmcodepp) = target;
   37:   (*vmcodepp)++;
   38: }
   39: 
   40: void printarg_i(Cell i)
   41: {
   42:   fprintf(vm_out, "%ld ", i);
   43: }
   44: 
   45: void printarg_target(Inst *target)
   46: {
   47:   fprintf(vm_out, "%p ", target);
   48: }
   49: 
   50: void printarg_a(char *a)
   51: {
   52:   fprintf(vm_out, "%p ", a);
   53: }
   54: 
   55: /* This language has separate name spaces for functions and variables;
   56:    this works because there are no function variables, and the syntax
   57:    makes it possible to differentiate between function and variable
   58:    reference */
   59: 
   60: typedef struct functab {
   61:   struct functab *next;
   62:   char *name;
   63:   Inst *start;
   64:   int params;
   65:   int nonparams;
   66: } functab;
   67: 
   68: functab *ftab=NULL;
   69: 
   70: /* note: does not check for double definitions */
   71: void insert_func(char *name, Inst *start, int locals, int nonparams)
   72: {
   73:   functab *node = malloc(sizeof(functab));
   74: 
   75:   node->next=ftab;
   76:   node->name=name;
   77:   node->start=start;
   78:   node->params=locals-nonparams;
   79:   node->nonparams=nonparams;
   80:   ftab=node;
   81: }
   82: 
   83: functab *lookup_func(char *name)
   84: {
   85:   functab *p;
   86: 
   87:   for (p=ftab; p!=NULL; p=p->next)
   88:     if (strcmp(p->name,name)==0)
   89:       return p;
   90:   fprintf(stderr, "undefined function %s", name);
   91:   exit(1);
   92: }
   93: 
   94: Inst *func_addr(char *name)
   95: {
   96:   return lookup_func(name)->start;
   97: }
   98: 
   99: Cell func_calladjust(char *name)
  100: {
  101:   return adjust(lookup_func(name)->nonparams);
  102: }
  103: 
  104: 
  105: typedef struct vartab {
  106:   struct vartab *next;
  107:   char *name;
  108:   int index;
  109: } vartab;
  110: 
  111: vartab* vtab;
  112: 
  113: /* no checking for double definitions */
  114: void insert_local(char *name)
  115: {
  116:   vartab *node = malloc(sizeof(vartab));
  117: 
  118:   locals++;
  119:   node->next=vtab;
  120:   node->name=name;
  121:   node->index=locals;
  122:   vtab = node;
  123: }
  124: 
  125: vartab *lookup_var(char *name)
  126: {
  127:   vartab *p;
  128: 
  129:   for (p=vtab; p!=NULL; p=p->next)
  130:     if (strcmp(p->name,name)==0)
  131:       return p;
  132:   fprintf(stderr, "undefined local variable %s", name);
  133:   exit(1);
  134: }
  135: 
  136: Cell var_offset(char *name)
  137: {
  138:   return (locals - lookup_var(name)->index + 2)*sizeof(Cell);
  139: }
  140: 
  141: #define CODE_SIZE 65536
  142: #define STACK_SIZE 65536
  143: typedef Cell (*engine_t)(Inst *ip0, Cell* sp, char* fp);
  144: 
  145: char *program_name;
  146: 
  147: int main(int argc, char **argv)
  148: {
  149:   int disassembling = 0;
  150:   int profiling = 0;
  151:   int c;
  152:   Inst vm_code[CODE_SIZE];
  153:   Inst *start;
  154:   Cell stack[STACK_SIZE];
  155:   engine_t runvm=engine;
  156: 
  157:   while ((c = getopt(argc, argv, "hdpt")) != -1) {
  158:     switch (c) {
  159:     default:
  160:     case 'h':
  161:     help:
  162:       fprintf(stderr, "\
  163: Usage: %s [options] file\n
  164: Options:\n
  165: -h	Print this message and exit\n\
  166: -d	disassemble VM program before execution\n\
  167: -p	profile VM code sequences (output on stderr)\n\
  168: -t	trace VM code execution (output on stderr)\n\
  169: ",
  170: 	      argv[0]);
  171:       exit(1);
  172:     case 'd':
  173:       disassembling=1;
  174:       break;
  175:     case 'p':
  176:       profiling=1;
  177:       runvm = engine_debug;
  178:       break;
  179:     case 't':
  180:       vm_debug=1;
  181:       runvm = engine_debug;
  182:       break;
  183:     }
  184:   }
  185:   if (optind+1 != argc) 
  186:     goto help;
  187:   program_name = argv[optind];
  188:   if ((yyin=fopen(program_name,"r"))==NULL) {
  189:     perror(argv[optind]);
  190:     exit(1);
  191:   }
  192: 
  193:   /* initialize everything */
  194:   vmcodep = vm_code;
  195:   vm_out = stderr;
  196:   (void)runvm(NULL,NULL,NULL); /* initialize vm_prim */
  197:   init_peeptable();
  198:   
  199:   if (yyparse())
  200:     exit(1);
  201: 
  202:   start=vmcodep;
  203:   gen_main_end();  
  204: 
  205:   if (disassembling)
  206:     vm_disassemble(vm_code, vmcodep, vm_prim);
  207: 
  208:   printf("result = %ld\n",runvm(start, stack+STACK_SIZE-1, NULL));
  209: 
  210:   return 0;
  211: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>