OpenCores
URL https://opencores.org/ocsvn/zipcpu/zipcpu/trunk

Subversion Repositories zipcpu

[/] [zipcpu/] [trunk/] [sw/] [zasm/] [zasm.y] - Blame information for rev 63

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 13 dgisselq
/*******************************************************************************
2
**
3
** Filename:    zasm.y
4
**
5
** Project:     Zip CPU -- a small, lightweight, RISC CPU core
6
**
7
** Purpose:     The parser for the Zip Assembler.  This is actually not just
8
**              the parser, but the main program as well.
9
**
10
** Creator:     Dan Gisselquist, Ph.D.
11
**              Gisselquist Tecnology, LLC
12
**
13
********************************************************************************
14
**
15
** Copyright (C) 2015, Gisselquist Technology, LLC
16
**
17
** This program is free software (firmware): you can redistribute it and/or
18
** modify it under the terms of  the GNU General Public License as published
19
** by the Free Software Foundation, either version 3 of the License, or (at
20
** your option) any later version.
21
**
22
** This program is distributed in the hope that it will be useful, but WITHOUT
23
** ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
24
** FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
25
** for more details.
26
**
27
** You should have received a copy of the GNU General Public License along
28
** with this program.  (It's in the $(ROOT)/doc directory, run make with no
29
** target there if the PDF file isn't present.)  If not, see
30
**  for a copy.
31
**
32
** License:     GPL, v3, as defined and found on www.gnu.org,
33
**              http://www.gnu.org/licenses/gpl.html
34
**
35
**
36
*******************************************************************************/
37
 
38
%{
39
 #include 
40 36 dgisselq
 #include 
41 13 dgisselq
 #include 
42
 #include "asmdata.h"
43
 
44 26 dgisselq
#define DEFAULT_OUTPUT_FNAME    "z.out"
45
#define YYDEBUG 1
46
 
47 13 dgisselq
  extern "C" int yylex(void);
48
  extern "C" int yyparse(void);
49
  // extern "C" FILE *yyin;
50
  void yyerror(const char *);
51
  unsigned int global_parser_pc;
52
  char *master_input_filename = NULL;
53
  extern int yylineno;
54
  char  *linecp = NULL; // A copy of the input line
55
%}
56
 
57
%token COMMA EQU PLUS MINUS TIMES HERE DOLLAR COLON
58
%token BOOLEANOR BITWISEOR BOOLEANAND BITWISEAND BITWISEXOR DOT
59
%token WORD FILL
60
%token LOADOP STOROP LDIOP
61
%token BAREOP BRANCHOP COND DUALOP IDENTIFIER INT LDHLOP REG SINGLOP
62
 
63
%union {
64
        ZPARSER::ZIPREG         u_reg;
65
        ZPARSER::ZIPCOND        u_cond;
66
        int                     u_ival;
67
        LEXOPCODE               u_op;
68
        char                    *u_id;
69
        ASMLINE                 *u_ln;
70
        AST                     *u_ast;
71
}
72
 
73
%type                   REG
74
%type           COND opcond
75
%type           INT
76
%type                   IDENTIFIER
77
%type                   BAREOP SINGLOP DUALOP BRANCHOP LDHLOP
78
%type                   unlabeledline instruction wordlist fillist opb
79
%type                   bareop singlop dualop loadop storop line
80
%type                   expr value multident
81
 
82 26 dgisselq
%left BOOLEANOR
83
%left BOOLEANAND
84
%left BITWISEOR BITWISEXOR
85
%left BITWISEAND
86 34 dgisselq
%left '%'
87 26 dgisselq
%left PLUS MINUS
88
%left TIMES '/'
89
 
90 13 dgisselq
%% /* The grammar follows */
91
 
92
input:
93
  %empty
94
| input line { if ($2) {objcode += $2; global_parser_pc += $2->nlines(); if ($2->isdefined()) delete $2; } }
95
;
96
 
97
line:
98
   '\n' { $$ = NULL; }
99
| unlabeledline '\n' { $$ = $1; }
100
| multident COLON unlabeledline '\n' {
101
        if ($1->m_node_type == 'I') {
102
                if (((AST_IDENTIFIER*)$1)->m_id[0] == 'L')
103
                        stb_define(((AST_IDENTIFIER *)$1)->m_id, new AST_NUMBER(global_parser_pc));
104
                else
105
                        gbl_define(((AST_IDENTIFIER *)$1)->m_id, new AST_NUMBER(global_parser_pc));
106
                delete $1;
107
                }
108
        $$ = $3;
109
        }
110
| multident COLON '\n' {
111
        if ($1->m_node_type == 'I') {
112
                if (((AST_IDENTIFIER*)$1)->m_id[0] == 'L')
113
                        stb_define(((AST_IDENTIFIER *)$1)->m_id, new AST_NUMBER(global_parser_pc));
114
                else
115
                        gbl_define(((AST_IDENTIFIER *)$1)->m_id, new AST_NUMBER(global_parser_pc));
116
                delete $1;
117
        }
118
        $$ = new VLINE();
119
        }
120
| multident EQU expr '\n' {
121
        if ($1->m_node_type == 'I') {
122
                stb_define(((AST_IDENTIFIER *)$1)->m_id, $3);
123
                delete $1;
124
        }
125
        $$ = new VLINE();
126
        }
127
;
128
 
129
unlabeledline:
130
  instruction   { $$ = $1; }
131
| WORD wordlist { $$ = $2; }
132
| FILL fillist { $$ = $2; }
133
;
134
 
135
wordlist:
136
  expr  {
137
        if ($1->isdefined())
138
                $$ = new DLINE($1->eval());
139
        else {
140
                $$ = new VLINE();
141
                yyerror("ERROR: word list undefined");
142
        }}
143 16 dgisselq
| wordlist COMMA expr {
144
        if ($3->isdefined()) {
145
                LLINE   *ln;
146
                if ($1->m_state == 'L') {
147
                        ln = ((LLINE *)$1);
148
                } else {
149
                        ln = new LLINE();
150
                        ln->addline($1);
151
                } ln->addline(new DLINE($3->eval()));
152
                $$ = ln;
153
        } else {
154 13 dgisselq
                $$ = new VLINE();
155
                yyerror("ERROR: word list undefined\n");
156
        }}
157
;
158
 
159
fillist:
160
  expr COMMA expr {
161
                if (($1->isdefined())&&($3->isdefined())) {
162
                        int     ntimes = $1->eval(),
163
                                val = $3->eval();
164
                        LLINE   *ln = new LLINE();
165
                        for(int i=0; i
166
                                ln->addline(new DLINE(val));
167
                        $$ = ln;
168
                } else {
169
                        yyerror("Fill list undefined\n");
170
                        $$ = new VLINE();
171
                }
172
        }
173
;
174
 
175
instruction:
176
  dualop  opb COMMA REG {
177
                $$ = $1;
178
                ((TLINE*)$1)->m_imm = ((TLINE*)$2)->m_imm; ((TLINE*)$2)->m_imm = NULL;
179
                ((TLINE*)$1)->m_opb = ((TLINE*)$2)->m_opb;
180
                ((TLINE*)$1)->m_opa = $4;
181
                if ($1->isdefined()) {
182
                        $$ = ((TLINE*)$1)->eval();
183
                        delete $1;
184
                        delete $2;
185
                }
186
        }
187
| dualop  opb COMMA multident {
188
                char    buf[256];
189
                sprintf(buf, "%s is not a register", ((AST_IDENTIFIER *)$4)->m_id.c_str());
190
                yyerror(buf);
191
                $$ = new VLINE();
192
                delete $1;
193
                delete $2;
194
                delete $4;
195
        }
196
| singlop opb   {
197
                $$ = $1;
198
                ((TLINE*)$1)->m_imm = ((TLINE*)$2)->m_imm; ((TLINE*)$2)->m_imm = NULL;
199
                ((TLINE*)$1)->m_opb = ((TLINE*)$2)->m_opb;
200
                if ($1->isdefined()) {
201
                        $$ = ((TLINE *)$1)->eval();
202
                        delete $1;
203
                }
204
        }
205
| bareop        { $$ = $1; }
206
| LDHLOP  opcond expr COMMA REG {
207
                TLINE *tln = new TLINE;
208
                tln->m_opcode = $1;
209
                tln->m_cond   = $2;
210
                tln->m_imm    = $3;
211
                tln->m_opa    = $5;
212
 
213
                if (tln->isdefined()) {
214
                        $$ = tln->eval();
215
                        delete tln;
216
                } else
217
                        $$ = tln;
218
        }
219
| LDHLOP  opcond expr COMMA multident {
220
                char    buf[256];
221
                sprintf(buf, "%s is not a register", ((AST_IDENTIFIER *)$5)->m_id.c_str());
222
                yyerror(buf);
223
                $$ = new VLINE();
224
                delete $3;
225
                delete $5;
226
        }
227
| LDIOP          expr COMMA REG {
228
                TLINE *tln = new TLINE;
229
                tln->m_opcode = OP_LDI;
230
                tln->m_cond   = ZPARSER::ZIPC_ALWAYS;
231
                tln->m_imm    = $2;
232
                tln->m_opa    = $4;
233
 
234
                if (tln->isdefined()) {
235
                        $$ = tln->eval();
236
                        delete tln;
237
                } else
238
                        $$ = tln;
239
        }
240
| LDIOP  expr COMMA multident {
241
                char    buf[256];
242
                sprintf(buf, "%s is not a register", ((AST_IDENTIFIER *)$4)->m_id.c_str());
243
                yyerror(buf);
244
                $$ = new VLINE();
245
                delete $2;
246
                delete $4;
247
        }
248
| BRANCHOP  expr        {
249
                TLINE *tln = new TLINE;
250
                tln->m_opcode = $1;
251
                tln->m_imm    = $2;
252
 
253
                if (tln->isdefined()) {
254
                        $$ = tln->eval();
255
                        delete tln;
256
                } else
257
                        $$ = tln;
258
        }
259
| loadop opb COMMA REG {
260
                TLINE *tln = new TLINE;
261
                ((TLINE*)$2)->m_opcode = OP_LOD;
262
                ((TLINE*)$2)->m_cond   = ((TLINE*)$1)->m_cond;
263
                ((TLINE*)$2)->m_opa    = $4;
264
 
265
                delete $1;
266
 
267
                if (((TLINE *)$2)->isdefined()) {
268
                        $$ = ((TLINE *)$2)->eval();
269
                        delete $2;
270
                } else
271
                        $$ = $2;
272
        }
273
| loadop opb COMMA multident {
274
                char    buf[256];
275
                sprintf(buf, "%s is not a register", ((AST_IDENTIFIER *)$4)->m_id.c_str());
276
                yyerror(buf);
277
                $$ = new VLINE();
278
                delete $1;
279
                delete $2;
280
                delete $4;
281
        }
282
| storop REG COMMA opb {
283
                TLINE *tln = new TLINE;
284
                tln->m_opcode = OP_STO;
285
                tln->m_cond   = ((TLINE*)$1)->m_cond;
286
                tln->m_imm    = ((TLINE*)$4)->m_imm;
287
                tln->m_opb    = ((TLINE*)$4)->m_opb;
288
                tln->m_opa    = $2;
289
 
290
                delete $1;
291
 
292
                if (tln->isdefined()) {
293
                        $$ = tln->eval();
294
                        delete tln;
295
                } else
296
                        $$ = tln;
297
        }
298
| storop multident COMMA opb {
299
                char    buf[256];
300
                sprintf(buf, "%s is not a register", ((AST_IDENTIFIER *)$2)->m_id.c_str());
301
                yyerror(buf);
302
                $$ = new VLINE();
303
                delete $1;
304
                delete $2;
305
                delete $4;
306
        }
307
;
308
 
309
dualop: DUALOP  opcond {
310
        TLINE *tln = new TLINE();
311
        tln->m_opcode = $1;
312
        tln->m_cond   = $2;
313
        $$ = tln;
314
        }
315
;
316
 
317
singlop: SINGLOP opcond {
318
        TLINE *tln = new TLINE();
319
        tln->m_opcode = $1;
320
        tln->m_cond   = $2;
321
        $$ = tln;
322
        }
323
;
324
 
325
storop: STOROP opcond {
326
        TLINE *tln = new TLINE();
327
        tln->m_opcode = OP_STO;
328
        tln->m_cond   = $2;
329
        $$ = tln;
330
        }
331
;
332
 
333
loadop: LOADOP opcond {
334
        TLINE *tln = new TLINE();
335
        tln->m_opcode = OP_LOD;
336
        tln->m_cond   = $2;
337
        $$ = tln;
338
        }
339
;
340
 
341
bareop: BAREOP  opcond {
342
        TLINE *tln = new TLINE();
343
        tln->m_opcode = $1;
344
        tln->m_cond   = $2;
345
        $$ = tln;
346
        }
347
;
348
 
349
opcond:
350
        COND    { $$ = $1; }
351
|       %empty  { $$ = ZPARSER::ZIPC_ALWAYS; }
352
;
353
 
354
opb:
355
        expr    {
356
                TLINE *tln = new TLINE();
357
                tln->m_imm = $1;
358
                $$ = tln;
359
        }
360
|       expr PLUS REG {
361
                TLINE *tln = new TLINE();
362
                tln->m_imm = $1;
363
                tln->m_opb = $3;
364
                $$ = tln;
365
        }
366
|       expr '(' REG ')' {
367
                TLINE *tln = new TLINE();
368
                tln->m_imm = $1;
369
                tln->m_opb = $3;
370
                $$ = tln;
371
        }
372
|       '(' REG ')' {
373
                TLINE *tln = new TLINE();
374
                tln->m_imm = new AST_NUMBER(0);
375
                tln->m_opb = $2;
376
                $$ = tln;
377
        }
378
|       REG {
379
                TLINE *tln = new TLINE();
380
                tln->m_imm = new AST_NUMBER(0);
381
                tln->m_opb = $1;
382
                $$ = tln;
383
        }
384
;
385
 
386
expr:
387
        value                   { $$ = $1; }
388 34 dgisselq
|       MINUS value %prec TIMES  { $$ = new AST_BRANCH('-',new AST_NUMBER(0), $2); }
389
|       expr PLUS expr          { $$ = new AST_BRANCH('+',$1,$3); }
390
|       expr MINUS expr         { $$ = new AST_BRANCH('-',$1,$3); }
391
|       expr TIMES expr         { $$ = new AST_BRANCH('*',$1,$3); }
392
|       expr '/' expr           { $$ = new AST_BRANCH('/',$1,$3); }
393
|       expr '%' expr           { $$ = new AST_BRANCH('%',$1,$3); }
394
|       expr BOOLEANOR expr     { $$ = new AST_BRANCH('o',$1,$3); }
395
|       expr BITWISEOR expr     { $$ = new AST_BRANCH('|',$1,$3); }
396
|       expr BOOLEANAND expr    { $$ = new AST_BRANCH('a',$1,$3); }
397
|       expr BITWISEAND expr    { $$ = new AST_BRANCH('&',$1,$3); }
398
|       expr BITWISEXOR expr    { $$ = new AST_BRANCH('^',$1,$3); }
399 13 dgisselq
|       '(' expr ')'            { $$ = $2; }
400
;
401
        /* expr OR  (|) value */
402
        /* expr XOR (^) value */
403
        /* expr AND (&) value */
404
 
405
value:
406
        INT     { $$ = new AST_NUMBER($1); }
407
| multident     { $$ = $1; }
408
| HERE          { $$ = new AST_NUMBER(global_parser_pc); }
409
;
410
 
411
multident:
412
        IDENTIFIER              { $$ = new AST_IDENTIFIER($1); delete $1; }
413
| multident DOT IDENTIFIER      { $$ = new AST_IDENTIFIER($1,$3); delete $3; }
414
;
415
%%
416
 
417
#include 
418
#include 
419 26 dgisselq
#include 
420 13 dgisselq
#include 
421
#include 
422
#include 
423 36 dgisselq
#include 
424 13 dgisselq
 
425
OBJFILE objcode;
426
 
427
void    yyerror(const char *str) {
428
        fprintf(stderr, "%s:%d: ERROR: %s\n", master_input_filename, yylineno, str);
429
        if (linecp) fprintf(stderr, "Offending line was: %s\n", linecp);
430
}
431
 
432 26 dgisselq
FILE    *run_preprocessor(pid_t &pid, const char *path = NULL, const char *zname = NULL) {
433 13 dgisselq
        int     pipefd[2];
434
 
435
        if (pipe(pipefd)!=0) {
436
                fprintf(stderr, "PIPE FAILED!\n");
437
                perror("O/S Err:");
438
                exit(-2);
439
        } if ((zname)&&(access(zname, R_OK)!=0)) { // if !zname, then use stdin
440
                fprintf(stderr, "Cannot open %s\n", zname);
441
                perror("O/S Err:");
442
                exit(-2);
443
        }
444
 
445
 
446
        if (0 == (pid = fork())) {
447
                int     fdin, fdout;
448
 
449
                // Child process -- run the preprocessor
450
 
451 16 dgisselq
                // Close the reader: we write only
452 13 dgisselq
                close(pipefd[0]);
453
 
454 16 dgisselq
                // Adjust stdout to write to our pipe instead of anywhere else
455 13 dgisselq
                fdout = pipefd[1];
456
                close(STDOUT_FILENO);
457
                dup2(fdout, STDOUT_FILENO);
458
 
459 16 dgisselq
                char    *zpp_path;
460
                if (path != NULL) {
461
                        zpp_path = new char[strlen(path+1+strlen("/zpp"))];
462
                        strcpy(zpp_path, path);
463
                        strcat(zpp_path, "/zpp");
464
                } else zpp_path = strdup("zpp");
465
 
466 13 dgisselq
                // This call should never return
467 16 dgisselq
                //      We have to pass the name here, rather than an open file,
468
                // since zpp needs to mark for us what file it is in at all
469
                // times.
470
                if (zname)
471
                        execlp(zpp_path, "zpp", zname, NULL);
472
                else
473
                        execlp(zpp_path, "zpp", NULL);
474 13 dgisselq
 
475
                fprintf(stderr, "Could not start pre-processor!\n");
476
                perror("O/S Err:");
477
 
478
                exit(-5);
479
        }
480
 
481
        close(pipefd[1]);
482
        return fdopen(pipefd[0], "r");
483
}
484
 
485 26 dgisselq
void    usage(void) {
486
        printf("USAGE: zasm [-h] [-d] [-E] [-o ]  [ ]* ...\n");
487
        printf("\t-d\tTurns on debugging in the parser\n");
488
        printf("\t-E\tProduces preprocessor output only\n");
489
        printf("\t-h\tDisplays this message\n");
490
        printf("\t-o \tWrites the output to .  The\n"
491
                "\t\tdefault output file is \"" DEFAULT_OUTPUT_FNAME "\".\n");
492
 
493
        printf("\t-I \tSearch  for include files.\n");
494
}
495
 
496 13 dgisselq
int     main(int argc, char **argv) {
497
        int     skp = 0;
498
        const char      *zout_fname = NULL;
499 16 dgisselq
        char            *path_to_zasm = NULL;
500
        bool    preprocess_only = false;
501 26 dgisselq
        FILE            *ppout;
502
        pid_t           zpp_pid;
503
        int             zpp_status;
504 36 dgisselq
        std::string     inclist;
505
        if (NULL != getenv("ZIPINC"))
506
                inclist = getenv("ZIPINC");
507 26 dgisselq
 
508 13 dgisselq
        master_input_filename = NULL;
509
 
510 16 dgisselq
        // Find what directory zasm is in, so that we can find zpp when
511
        // necessary.
512
        path_to_zasm = NULL;
513
        if (strchr(argv[0], '/')) {
514
                path_to_zasm = strdup(argv[0]);
515
                char *ptr = strrchr(path_to_zasm,'/');
516
                *ptr = '\0';
517
        }
518
 
519 13 dgisselq
        skp=1;
520
        for(int argn=0; argn+skp
521
                if (argv[argn+skp][0] == '-') {
522
                        if (argv[argn+skp][1] == 'o') {
523
                                if (zout_fname)
524
                                        free((void *)zout_fname);
525
                                zout_fname = strdup(argv[argn+skp+1]);
526
                                skp++;
527 16 dgisselq
                        } else if (argv[argn+skp][1] == 'E')
528
                                preprocess_only = true;
529 36 dgisselq
                        else if (argv[argn+skp][1] == 'I') {
530
                                if (argv[argn+skp][2]) {
531
                                        if (inclist.size() != 0) {
532
                                                inclist += std::string(":");
533
                                                inclist += &argv[argn+skp][2];
534
                                        } else
535
                                                inclist = &argv[argn+skp][2];
536
                                } else if (argn+skp+1
537
                                        if (inclist.size() != 0) {
538
                                                inclist += std::string(":");
539 46 dgisselq
                                                inclist += argv[argn+skp+1];
540 36 dgisselq
                                        } else
541 46 dgisselq
                                                inclist = argv[argn+skp+1];
542
                                        skp++;
543 36 dgisselq
                                }
544
                        } else if (argv[argn+skp][1] == 'd')
545 26 dgisselq
                                yydebug = 1;
546
                        else if (argv[argn+skp][1] == 'h') {
547
                                usage();
548
                                exit(0);
549
                        }
550 13 dgisselq
 
551
                        skp++;
552 46 dgisselq
                        argn--;
553
                } else {
554
                        argv[argn] = argv[argn+skp];
555
                }
556 13 dgisselq
        } argc -= skp;
557
 
558 26 dgisselq
        if (zout_fname) {
559
                for(int argn=0; argn
560
                        if (strcmp(zout_fname, argv[argn])==0) {
561
                                fprintf(stderr, "ERR: Cowardly refusing to overwrite \'%s\'\n", zout_fname);
562
                                exit(-2);
563
                        }
564
                }
565
        }
566
 
567 16 dgisselq
        if (preprocess_only) {
568
                objcode.open("/dev/null");
569 26 dgisselq
                if (zout_fname)
570
                        ppout = fopen(zout_fname, "w");
571
                else
572
                        ppout = stdout;
573 16 dgisselq
        } else {
574
                if (!zout_fname)
575 26 dgisselq
                        zout_fname = DEFAULT_OUTPUT_FNAME;
576 13 dgisselq
 
577 16 dgisselq
                objcode.open(zout_fname);
578
        }
579 13 dgisselq
 
580 36 dgisselq
        setenv("ZIPINC",inclist.c_str(), 1);
581 13 dgisselq
        master_input_filename = NULL;
582
 
583
        if (argc > 0) {
584
                for(int argn=0; argn
585
                        extern  FILE    *yyin;
586
                        extern  void    yyrestart(FILE *);
587
                        FILE    *tst;
588
 
589
                        create_new_context();
590
                        if (master_input_filename)
591
                                free(master_input_filename);
592
                        master_input_filename = strdup(argv[argn]);
593 16 dgisselq
                        if (preprocess_only) {
594 26 dgisselq
                                FILE    *fp = run_preprocessor(zpp_pid, path_to_zasm, master_input_filename);
595 16 dgisselq
                                int     ch;
596
                                while(EOF != (ch = fgetc(fp)))
597 26 dgisselq
                                        fputc(ch, ppout);
598
                                waitpid(zpp_pid, &zpp_status, WNOHANG);
599 16 dgisselq
                        } else {
600 26 dgisselq
                                yyrestart(run_preprocessor(zpp_pid, path_to_zasm, master_input_filename));
601 16 dgisselq
                                yylineno = 1;
602
                                yyparse();
603 26 dgisselq
                                waitpid(zpp_pid, &zpp_status, WNOHANG);
604 16 dgisselq
                        }
605 13 dgisselq
                }
606
        } else { // Run from Stdin
607
                extern  FILE    *yyin;
608
                extern  void    yyrestart(FILE *);
609
 
610
                create_new_context();
611
                master_input_filename = strdup("(stdin)");
612 16 dgisselq
                if (preprocess_only) {
613
                        int     ch;
614 26 dgisselq
                                FILE    *fp = run_preprocessor(zpp_pid, path_to_zasm, master_input_filename);
615 16 dgisselq
                        while(EOF != (ch = fgetc(fp)))
616 26 dgisselq
                                fputc(ch, ppout);
617
                        waitpid(zpp_pid, &zpp_status, WNOHANG);
618 16 dgisselq
                } else {
619 26 dgisselq
                        yyin = run_preprocessor(zpp_pid, NULL);
620 16 dgisselq
                        yyrestart(yyin);
621
                        yyparse();
622 26 dgisselq
                        waitpid(zpp_pid, &zpp_status, WNOHANG);
623 16 dgisselq
                }
624 13 dgisselq
        }
625
 
626 26 dgisselq
        if (0 != WEXITSTATUS(zpp_status)) {
627
                if (!preprocess_only) {
628
                        objcode.close();
629
                        unlink(zout_fname);
630
                }
631
        } if (!objcode.reduce())
632 13 dgisselq
                fprintf(stderr, "Not all symbols defined!\n");
633
}
634
 
635
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.