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>