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