File:  [gforth] / gforth / vmgen-ex2 / support.c
Revision 1.1: download - view: text, annotated - select for diffs
Sun Jun 2 15:46:18 2002 UTC (17 years, 7 months ago) by anton
Branches: MAIN
CVS tags: HEAD
vmgen-related changes:
in prims2x:
  Conversion macros for single items now take 2 arguments
  Converting from two items to a type has changed order
  argument printing for disassembler disabled (for now)
  disassembler now also uses VM_IS_INST
in Gforth and vmgen-ex: adapted to work with changed prims2x
new: vmgen-ex2: uses union for Cell instead of casting (lots of
   changes compared to 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, long i)
   29: {
   30:   vm_i2Cell(i, *((Cell *) *vmcodepp));
   31:   (*vmcodepp)++;
   32: }
   33: 
   34: void genarg_target(Inst **vmcodepp, Inst *target)
   35: {
   36:   vm_target2Cell(target, *((Cell *) *vmcodepp));
   37:   (*vmcodepp)++;
   38: }
   39: 
   40: void printarg_i(long 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: void printarg_Cell(Cell i)
   56: {
   57:   fprintf(vm_out, "0x%lx ", i.i);
   58: }
   59: 
   60: /* This language has separate name spaces for functions and variables;
   61:    this works because there are no function variables, and the syntax
   62:    makes it possible to differentiate between function and variable
   63:    reference */
   64: 
   65: typedef struct functab {
   66:   struct functab *next;
   67:   char *name;
   68:   Inst *start;
   69:   int params;
   70:   int nonparams;
   71: } functab;
   72: 
   73: functab *ftab=NULL;
   74: 
   75: /* note: does not check for double definitions */
   76: void insert_func(char *name, Inst *start, int locals, int nonparams)
   77: {
   78:   functab *node = malloc(sizeof(functab));
   79: 
   80:   node->next=ftab;
   81:   node->name=name;
   82:   node->start=start;
   83:   node->params=locals-nonparams;
   84:   node->nonparams=nonparams;
   85:   ftab=node;
   86: }
   87: 
   88: functab *lookup_func(char *name)
   89: {
   90:   functab *p;
   91: 
   92:   for (p=ftab; p!=NULL; p=p->next)
   93:     if (strcmp(p->name,name)==0)
   94:       return p;
   95:   fprintf(stderr, "undefined function %s", name);
   96:   exit(1);
   97: }
   98: 
   99: Inst *func_addr(char *name)
  100: {
  101:   return lookup_func(name)->start;
  102: }
  103: 
  104: long func_calladjust(char *name)
  105: {
  106:   return adjust(lookup_func(name)->nonparams);
  107: }
  108: 
  109: 
  110: typedef struct vartab {
  111:   struct vartab *next;
  112:   char *name;
  113:   int index;
  114: } vartab;
  115: 
  116: vartab* vtab;
  117: 
  118: /* no checking for double definitions */
  119: void insert_local(char *name)
  120: {
  121:   vartab *node = malloc(sizeof(vartab));
  122: 
  123:   locals++;
  124:   node->next=vtab;
  125:   node->name=name;
  126:   node->index=locals;
  127:   vtab = node;
  128: }
  129: 
  130: vartab *lookup_var(char *name)
  131: {
  132:   vartab *p;
  133: 
  134:   for (p=vtab; p!=NULL; p=p->next)
  135:     if (strcmp(p->name,name)==0)
  136:       return p;
  137:   fprintf(stderr, "undefined local variable %s", name);
  138:   exit(1);
  139: }
  140: 
  141: long var_offset(char *name)
  142: {
  143:   return (locals - lookup_var(name)->index + 2)*sizeof(Cell);
  144: }
  145: 
  146: #define CODE_SIZE 65536
  147: #define STACK_SIZE 65536
  148: typedef long (*engine_t)(Inst *ip0, Cell* sp, char* fp);
  149: 
  150: char *program_name;
  151: 
  152: int main(int argc, char **argv)
  153: {
  154:   int disassembling = 0;
  155:   int profiling = 0;
  156:   int c;
  157:   Inst vm_code[CODE_SIZE];
  158:   Inst *start;
  159:   Cell stack[STACK_SIZE];
  160:   engine_t runvm=engine;
  161: 
  162:   while ((c = getopt(argc, argv, "hdpt")) != -1) {
  163:     switch (c) {
  164:     default:
  165:     case 'h':
  166:     help:
  167:       fprintf(stderr, "\
  168: Usage: %s [options] file\n
  169: Options:\n
  170: -h	Print this message and exit\n\
  171: -d	disassemble VM program before execution\n\
  172: -p	profile VM code sequences (output on stderr)\n\
  173: -t	trace VM code execution (output on stderr)\n\
  174: ",
  175: 	      argv[0]);
  176:       exit(1);
  177:     case 'd':
  178:       disassembling=1;
  179:       break;
  180:     case 'p':
  181:       profiling=1;
  182:       runvm = engine_debug;
  183:       break;
  184:     case 't':
  185:       vm_debug=1;
  186:       runvm = engine_debug;
  187:       break;
  188:     }
  189:   }
  190:   if (optind+1 != argc) 
  191:     goto help;
  192:   program_name = argv[optind];
  193:   if ((yyin=fopen(program_name,"r"))==NULL) {
  194:     perror(argv[optind]);
  195:     exit(1);
  196:   }
  197: 
  198:   /* initialize everything */
  199:   vmcodep = vm_code;
  200:   vm_out = stderr;
  201:   (void)runvm(NULL,NULL,NULL); /* initialize vm_prim */
  202:   init_peeptable();
  203:   
  204:   if (yyparse())
  205:     exit(1);
  206: 
  207:   start=vmcodep;
  208:   gen_main_end();
  209:   vmcode_end=vmcodep;
  210: 
  211:   if (disassembling)
  212:     vm_disassemble(vm_code, vmcodep, vm_prim);
  213: 
  214:   printf("result = %ld\n",runvm(start, stack+STACK_SIZE-1, NULL));
  215: 
  216:   if (profiling)
  217:     vm_print_profile(vm_out);
  218: 
  219:   return 0;
  220: }

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