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

Subversion Repositories jtag_stapl_player

[/] [jtag_stapl_player/] [trunk/] [jamsym.c] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 sukhanov
/****************************************************************************/
2
/*                                                                                                                                                      */
3
/*      Module:                 jamsym.c                                                                                                */
4
/*                                                                                                                                                      */
5
/*                                      Copyright (C) Altera Corporation 1997                                   */
6
/*                                                                                                                                                      */
7
/*      Description:    Functions for maintaining symbol table, including               */
8
/*                                      adding a synbol, searching for a symbol, and                    */
9
/*                                      modifying the value associated with a symbol                    */
10
/*                                                                                                                                                      */
11
/*      Revisions:              1.1 added support for dynamic memory allocation, made   */
12
/*                                      jam_symbol_table a pointer table instead of a table of  */
13
/*                                      structures.  Actual symbols now live at the top of the  */
14
/*                                      workspace, and grow dynamically downwards in memory.    */
15
/*                                                                                                                                                      */
16
/****************************************************************************/
17
 
18
/****************************************************************************/
19
/*                                                                                                                                                      */
20
/*      Actel version 1.1             May 2003                                                                  */
21
/*                                                                                                                                                      */
22
/****************************************************************************/
23
 
24
#include "jamexprt.h"
25
#include "jamdefs.h"
26
#include "jamsym.h"
27
#include "jamheap.h"
28
#include "jamutil.h"
29
 
30
/****************************************************************************/
31
/*                                                                                                                                                      */
32
/*      Global variables                                                                                                                */
33
/*                                                                                                                                                      */
34
/****************************************************************************/
35
 
36
JAMS_SYMBOL_RECORD **jam_symbol_table = NULL;
37
 
38
void *jam_symbol_bottom = NULL;
39
 
40
extern BOOL jam_checking_uses_list;
41
 
42
/****************************************************************************/
43
/*                                                                                                                                                      */
44
 
45
JAM_RETURN_TYPE jam_init_symbol_table()
46
 
47
/*                                                                                                                                                      */
48
/*      Description:    Initializes the symbol table.  The symbol table is              */
49
/*                                      located at the beginning of the workspace buffer.               */
50
/*                                                                                                                                                      */
51
/*      Returns:                JAMC_SUCCESS for success, or JAMC_OUT_OF_MEMORY if the  */
52
/*                                      size of the workspace buffer is too small to hold the   */
53
/*                                      desired number of symbol records.                                               */
54
/*                                                                                                                                                      */
55
/****************************************************************************/
56
{
57
        int index = 0;
58
        JAM_RETURN_TYPE status = JAMC_SUCCESS;
59
 
60
        if (jam_workspace != NULL)
61
        {
62
                jam_symbol_table = (JAMS_SYMBOL_RECORD **) jam_workspace;
63
 
64
                jam_symbol_bottom = (void *) (((long)jam_workspace) +
65
                        ((long)jam_workspace_size));
66
 
67
                if (jam_workspace_size <
68
                        (JAMC_MAX_SYMBOL_COUNT * sizeof(void *)))
69
                {
70
                        status = JAMC_OUT_OF_MEMORY;
71
                }
72
        }
73
        else
74
        {
75
                jam_symbol_table = (JAMS_SYMBOL_RECORD **) jam_malloc(
76
                        (JAMC_MAX_SYMBOL_COUNT * sizeof(void *)));
77
 
78
                if (jam_symbol_table == NULL)
79
                {
80
                        status = JAMC_OUT_OF_MEMORY;
81
                }
82
        }
83
 
84
        if (status == JAMC_SUCCESS)
85
        {
86
                for (index = 0; index < JAMC_MAX_SYMBOL_COUNT; ++index)
87
                {
88
                        jam_symbol_table[index] = NULL;
89
                }
90
        }
91
 
92
        return (status);
93
}
94
 
95
void jam_free_symbol_table()
96
{
97
        int hash = 0;
98
        JAMS_SYMBOL_RECORD *symbol_record = NULL;
99
        JAMS_SYMBOL_RECORD *next = NULL;
100
 
101
        if ((jam_symbol_table != NULL) && (jam_workspace == NULL))
102
        {
103
                for (hash = 0; hash < JAMC_MAX_SYMBOL_COUNT; ++hash)
104
                {
105
                        symbol_record = jam_symbol_table[hash];
106
                        while (symbol_record != NULL)
107
                        {
108
                                next = symbol_record->next;
109
                                jam_free(symbol_record);
110
                                symbol_record = next;
111
                        }
112
                }
113
 
114
                jam_free(jam_symbol_table);
115
        }
116
}
117
 
118
/****************************************************************************/
119
/*                                                                                                                                                      */
120
 
121
BOOL jam_check_init_list
122
(
123
        char *name,
124
        long *value
125
)
126
 
127
/*                                                                                                                                                      */
128
/*      Description:    Compares variable name to names in initialization list  */
129
/*                                      and, if name is found, returns the corresponding                */
130
/*                                      initialization value for the variable.                                  */
131
/*                                                                                                                                                      */
132
/*      Returns:                TRUE if variable was found, else FALSE                                  */
133
/*                                                                                                                                                      */
134
/****************************************************************************/
135
{
136
        char r, l;
137
        int ch_index = 0;
138
        int init_entry = 0;
139
        char *init_string = NULL;
140
        long val;
141
        BOOL match = FALSE;
142
        BOOL negate = FALSE;
143
        BOOL status = FALSE;
144
 
145
        if (jam_init_list != NULL)
146
        {
147
                while ((!match) && (jam_init_list[init_entry] != NULL))
148
                {
149
                        init_string = jam_init_list[init_entry];
150
                        match = TRUE;
151
                        ch_index = 0;
152
                        do
153
                        {
154
                                r = jam_toupper(init_string[ch_index]);
155
                                if (!jam_is_name_char(r)) r = '\0';
156
                                l = name[ch_index];
157
                                match = (r == l);
158
                                ++ch_index;
159
                        }
160
                        while (match && (r != '\0') && (l != '\0'));
161
 
162
                        if (match)
163
                        {
164
                                --ch_index;
165
                                while (jam_isspace(init_string[ch_index])) ++ch_index;
166
                                if (init_string[ch_index] == JAMC_EQUAL_CHAR)
167
                                {
168
                                        ++ch_index;
169
                                        while (jam_isspace(init_string[ch_index])) ++ch_index;
170
 
171
                                        if (init_string[ch_index] == JAMC_MINUS_CHAR)
172
                                        {
173
                                                ++ch_index;
174
                                                negate = TRUE;
175
                                        }
176
 
177
                                        if (jam_isdigit(init_string[ch_index]))
178
                                        {
179
                                                val = jam_atol(&init_string[ch_index]);
180
 
181
                                                if (negate) val = 0L - val;
182
 
183
                                                if (value != NULL) *value = val;
184
 
185
                                                status = TRUE;
186
                                        }
187
                                }
188
                        }
189
                        else
190
                        {
191
                                ++init_entry;
192
                        }
193
                }
194
        }
195
 
196
        return (status);
197
}
198
 
199
/****************************************************************************/
200
/*                                                                                                                                                      */
201
 
202
int jam_hash
203
(
204
        char *name
205
)
206
 
207
/*                                                                                                                                                      */
208
/*      Description:    Calcluates 'hash value' for a symbolic name.  This is   */
209
/*                                      a pseudo-random number which is used as an offset into  */
210
/*                                      the symbol table, as the initial position for the               */
211
/*                                      symbol record.                                                                                  */
212
/*                                                                                                                                                      */
213
/*      Returns:                An integer between 0 and JAMC_MAX_SYMBOL_COUNT-1                */
214
/*                                                                                                                                                      */
215
/****************************************************************************/
216
{
217
        int ch_index = 0;
218
        int hash = 0;
219
 
220
        while ((ch_index < JAMC_MAX_NAME_LENGTH) && (name[ch_index] != '\0'))
221
        {
222
                hash <<= 1;
223
                hash += (name[ch_index] & 0x1f);
224
                ++ch_index;
225
        }
226
        if (hash < 0) hash = 0 - hash;
227
 
228
        return (hash % JAMC_MAX_SYMBOL_COUNT);
229
}
230
 
231
/****************************************************************************/
232
/*                                                                                                                                                      */
233
 
234
JAM_RETURN_TYPE jam_add_symbol
235
(
236
        JAME_SYMBOL_TYPE type,
237
        char *name,
238
        long value,
239
        long position
240
)
241
 
242
/*                                                                                                                                                      */
243
/*      Description:    Adds a new symbol to the symbol table.  If the symbol   */
244
/*                                      name already exists in the symbol table, it is an error */
245
/*                                      unless the symbol type and the position in the file             */
246
/*                                      where the symbol was declared are identical.  This is   */
247
/*                                      necessary to allow labels and variable declarations             */
248
/*                                      inside loops and subroutines where they may be                  */
249
/*                                      encountered multiple times.                                                             */
250
/*                                                                                                                                                      */
251
/*      Returns:                JAMC_SUCCESS for success, or JAMC_REDEFINED_SYMBOL              */
252
/*                                      if symbol was already declared elsewhere, or                    */
253
/*                                      JAMC_OUT_OF_MEMORY if symbol table is full.                             */
254
/*                                                                                                                                                      */
255
/****************************************************************************/
256
{
257
        char r, l;
258
        int ch_index = 0;
259
        int hash = 0;
260
        long init_list_value = 0L;
261
        BOOL match = FALSE;
262
        BOOL identical_redeclaration = FALSE;
263
        JAM_RETURN_TYPE status = JAMC_SUCCESS;
264
        JAMS_SYMBOL_RECORD *symbol_record = NULL;
265
        JAMS_SYMBOL_RECORD *prev_symbol_record = NULL;
266
 
267
        /*
268
        *       Check for legal characters in name, and legal name length
269
        */
270
        while (name[ch_index] != JAMC_NULL_CHAR)
271
        {
272
                if (!jam_is_name_char(name[ch_index++])) status = JAMC_ILLEGAL_SYMBOL;
273
        }
274
 
275
        if ((ch_index == 0) || (ch_index > JAMC_MAX_NAME_LENGTH))
276
        {
277
                status = JAMC_ILLEGAL_SYMBOL;
278
        }
279
 
280
        /*
281
        *       Get hash key for this name
282
        */
283
        hash = jam_hash(name);
284
 
285
        /*
286
        *       Get pointer to first symbol record corresponding to this hash key
287
        */
288
        symbol_record = jam_symbol_table[hash];
289
 
290
        /*
291
        *       Then check for duplicate entry in symbol table
292
        */
293
        while ((status == JAMC_SUCCESS) && (symbol_record != NULL) &&
294
                (!identical_redeclaration))
295
        {
296
                match = TRUE;
297
                ch_index = 0;
298
                do
299
                {
300
                        r = symbol_record->name[ch_index];
301
                        l = name[ch_index];
302
                        match = (r == l);
303
                        ++ch_index;
304
                }
305
                while (match && (r != '\0') && (l != '\0'));
306
 
307
                if (match)
308
                {
309
                        /*
310
                        *       Check if symbol was already declared identically
311
                        *       (same name, type, and source position)
312
                        */
313
                        if ((symbol_record->position == position) &&
314
                                (jam_phase == JAM_DATA_PHASE))
315
                        {
316
                                if ((type == JAM_INTEGER_ARRAY_WRITABLE) &&
317
                                        (symbol_record->type == JAM_INTEGER_ARRAY_INITIALIZED))
318
                                {
319
                                        type = JAM_INTEGER_ARRAY_INITIALIZED;
320
                                }
321
 
322
                                if ((type == JAM_BOOLEAN_ARRAY_WRITABLE) &&
323
                                        (symbol_record->type == JAM_BOOLEAN_ARRAY_INITIALIZED))
324
                                {
325
                                        type = JAM_BOOLEAN_ARRAY_INITIALIZED;
326
                                }
327
                        }
328
 
329
                        if ((symbol_record->type == type) &&
330
                                (symbol_record->position == position))
331
                        {
332
                                /*
333
                                *       For identical redeclaration, simply assign the value
334
                                */
335
                                identical_redeclaration = TRUE;
336
 
337
                                if (jam_version != 2)
338
                                {
339
                                        symbol_record->value = value;
340
                                }
341
                                else
342
                                {
343
                                        if ((type != JAM_PROCEDURE_BLOCK) &&
344
                                                (type != JAM_DATA_BLOCK) &&
345
                                                (jam_current_block != NULL) &&
346
                                                (jam_current_block->type == JAM_PROCEDURE_BLOCK))
347
                                        {
348
                                                symbol_record->value = value;
349
                                        }
350
                                }
351
                        }
352
                        else
353
                        {
354
                                status = JAMC_REDEFINED_SYMBOL;
355
                        }
356
                }
357
 
358
                prev_symbol_record = symbol_record;
359
                symbol_record = symbol_record->next;
360
        }
361
 
362
        /*
363
        *       If no duplicate entry found, add the symbol
364
        */
365
        if ((status == JAMC_SUCCESS) && (symbol_record == NULL) &&
366
                (!identical_redeclaration))
367
        {
368
                /*
369
                *       Check initialization list -- if matching name is found,
370
                *       override the initialization value with the new value
371
                */
372
                if (((type == JAM_INTEGER_SYMBOL) || (type == JAM_BOOLEAN_SYMBOL)) &&
373
                        (jam_init_list != NULL))
374
                {
375
                        if ((jam_version != 2) &&
376
                                jam_check_init_list(name, &init_list_value))
377
                        {
378
                                /* value was found -- override old value */
379
                                value = init_list_value;
380
                        }
381
                }
382
 
383
                /*
384
                *       Add the symbol
385
                */
386
                if (jam_workspace != NULL)
387
                {
388
                        jam_symbol_bottom = (void *)
389
                                (((long)jam_symbol_bottom) - sizeof(JAMS_SYMBOL_RECORD));
390
 
391
                        symbol_record = (JAMS_SYMBOL_RECORD *) jam_symbol_bottom;
392
 
393
                        if ((long)jam_heap_top > (long)jam_symbol_bottom)
394
                        {
395
                                status = JAMC_OUT_OF_MEMORY;
396
                        }
397
                }
398
                else
399
                {
400
                        symbol_record = (JAMS_SYMBOL_RECORD *)
401
                                jam_malloc(sizeof(JAMS_SYMBOL_RECORD));
402
 
403
                        if (symbol_record == NULL)
404
                        {
405
                                status = JAMC_OUT_OF_MEMORY;
406
                        }
407
                }
408
 
409
                if (status == JAMC_SUCCESS)
410
                {
411
                        symbol_record->type = type;
412
                        symbol_record->value = value;
413
                        symbol_record->position = position;
414
                        symbol_record->parent = jam_current_block;
415
                        symbol_record->next = NULL;
416
 
417
                        if (prev_symbol_record == NULL)
418
                        {
419
                                jam_symbol_table[hash] = symbol_record;
420
                        }
421
                        else
422
                        {
423
                                prev_symbol_record->next = symbol_record;
424
                        }
425
 
426
                        ch_index = 0;
427
                        while ((ch_index < JAMC_MAX_NAME_LENGTH) &&
428
                                (name[ch_index] != '\0'))
429
                        {
430
                                symbol_record->name[ch_index] = name[ch_index];
431
                                ++ch_index;
432
                        }
433
                        symbol_record->name[ch_index] = '\0';
434
                }
435
        }
436
 
437
        return (status);
438
}
439
 
440
/****************************************************************************/
441
/*                                                                                                                                                      */
442
 
443
JAM_RETURN_TYPE jam_get_symbol_record
444
(
445
        char *name,
446
        JAMS_SYMBOL_RECORD **symbol_record
447
)
448
 
449
/*                                                                                                                                                      */
450
/*      Description:    Searches in symbol table for a symbol record with               */
451
/*                                      matching name.                                                                                  */
452
/*                                                                                                                                                      */
453
/*      Return:                 Pointer to symbol record, or NULL if symbol not found   */
454
/*                                                                                                                                                      */
455
/****************************************************************************/
456
{
457
        char r, l;
458
        char save_ch = 0;
459
        int ch_index = 0;
460
        int hash = 0;
461
        int name_begin = 0;
462
        int name_end = 0;
463
        BOOL match = FALSE;
464
        JAMS_SYMBOL_RECORD *tmp_symbol_record = NULL;
465
        JAM_RETURN_TYPE status = JAMC_UNDEFINED_SYMBOL;
466
 
467
        /*
468
        *       Get hash key for this name
469
        */
470
        hash = jam_hash(name);
471
 
472
        /*
473
        *       Get pointer to first symbol record corresponding to this hash key
474
        */
475
        tmp_symbol_record = jam_symbol_table[hash];
476
 
477
        /*
478
        *       Search for name in symbol table
479
        */
480
        while ((!match) && (tmp_symbol_record != NULL))
481
        {
482
                match = TRUE;
483
                ch_index = 0;
484
                do
485
                {
486
                        r = tmp_symbol_record->name[ch_index];
487
                        l = name[ch_index];
488
                        match = (r == l);
489
                        ++ch_index;
490
                }
491
                while (match && (r != '\0') && (l != '\0'));
492
 
493
                if (match)
494
                {
495
                        status = JAMC_SUCCESS;
496
                }
497
                else
498
                {
499
                        tmp_symbol_record = tmp_symbol_record->next;
500
                }
501
        }
502
 
503
        /*
504
        *       For Jam version 2, check that symbol is in scope
505
        */
506
        if ((status == JAMC_SUCCESS) && (jam_version == 2))
507
        {
508
                if (jam_checking_uses_list &&
509
                        ((tmp_symbol_record->type == JAM_PROCEDURE_BLOCK) ||
510
                        (tmp_symbol_record->type == JAM_DATA_BLOCK)))
511
                {
512
                        /* ignore scope rules when validating USES list */
513
                        status = JAMC_SUCCESS;
514
                }
515
                else
516
                if ((tmp_symbol_record->parent != NULL) &&
517
                        (tmp_symbol_record->parent != jam_current_block) &&
518
                        (tmp_symbol_record != jam_current_block))
519
                {
520
                        JAMS_SYMBOL_RECORD *parent = tmp_symbol_record->parent;
521
                        JAMS_HEAP_RECORD *heap_record = NULL;
522
                        char *parent_name = NULL;
523
                        char *uses_list = NULL;
524
 
525
                        status = JAMC_SCOPE_ERROR;
526
 
527
                        /*
528
                        *       If the symbol in question is a procedure name, check that IT
529
                        *       itself is in the uses list, instead of looking for its parent
530
                        */
531
                        if (tmp_symbol_record->type == JAM_PROCEDURE_BLOCK)
532
                        {
533
                                parent = tmp_symbol_record;
534
                        }
535
 
536
                        if (parent != NULL)
537
                        {
538
                                parent_name = parent->name;
539
                        }
540
 
541
                        if ((jam_current_block != NULL) &&
542
                                (jam_current_block->type == JAM_PROCEDURE_BLOCK))
543
                        {
544
                                heap_record = (JAMS_HEAP_RECORD *) jam_current_block->value;
545
 
546
                                if (heap_record != NULL)
547
                                {
548
                                        uses_list = (char *) heap_record->data;
549
                                }
550
                        }
551
 
552
                        if ((uses_list != NULL) && (parent_name != NULL))
553
                        {
554
                                name_begin = 0;
555
                                ch_index = 0;
556
                                while ((uses_list[ch_index] != JAMC_NULL_CHAR) &&
557
                                        (status != JAMC_SUCCESS))
558
                                {
559
                                        name_end = 0;
560
                                        while ((uses_list[ch_index] != JAMC_NULL_CHAR) &&
561
                                                (!jam_is_name_char(uses_list[ch_index])))
562
                                        {
563
                                                ++ch_index;
564
                                        }
565
                                        if (jam_is_name_char(uses_list[ch_index]))
566
                                        {
567
                                                name_begin = ch_index;
568
                                        }
569
                                        while ((uses_list[ch_index] != JAMC_NULL_CHAR) &&
570
                                                (jam_is_name_char(uses_list[ch_index])))
571
                                        {
572
                                                ++ch_index;
573
                                        }
574
                                        name_end = ch_index;
575
 
576
                                        if (name_end > name_begin)
577
                                        {
578
                                                save_ch = uses_list[name_end];
579
                                                uses_list[name_end] = JAMC_NULL_CHAR;
580
                                                if (jam_strcmp(&uses_list[name_begin],
581
                                                        parent_name) == 0)
582
                                                {
583
                                                        /* symbol is in scope */
584
                                                        status = JAMC_SUCCESS;
585
                                                }
586
                                                uses_list[name_end] = save_ch;
587
                                        }
588
                                }
589
                        }
590
                }
591
        }
592
 
593
        if (status == JAMC_SUCCESS)
594
        {
595
                if (symbol_record == NULL)
596
                {
597
                        status = JAMC_INTERNAL_ERROR;
598
                }
599
                else
600
                {
601
                        *symbol_record = tmp_symbol_record;
602
                }
603
        }
604
        return (status);
605
}
606
 
607
/****************************************************************************/
608
/*                                                                                                                                                      */
609
 
610
JAM_RETURN_TYPE jam_get_symbol_value
611
(
612
        JAME_SYMBOL_TYPE type,
613
        char *name,
614
        long *value
615
)
616
 
617
/*                                                                                                                                                      */
618
/*      Description:    Gets the value of a symbol based on the name and                */
619
/*                                      symbol type.                                                                                    */
620
/*                                                                                                                                                      */
621
/*      Returns:                JAMC_SUCCESS for success, else JAMC_UNDEFINED_SYMBOL    */
622
/*                                      if symbol is not found                                                                  */
623
/*                                                                                                                                                      */
624
/****************************************************************************/
625
{
626
        JAM_RETURN_TYPE status = JAMC_UNDEFINED_SYMBOL;
627
        JAMS_SYMBOL_RECORD *symbol_record = NULL;
628
 
629
        status = jam_get_symbol_record(name, &symbol_record);
630
 
631
        if ((status == JAMC_SUCCESS) && (symbol_record != NULL))
632
        {
633
                /*
634
                *       If type and name match, return the value
635
                */
636
                if (symbol_record->type == type)
637
                {
638
                        if (value != NULL)
639
                        {
640
                                *value = symbol_record->value;
641
                        }
642
                        else
643
                        {
644
                                status = JAMC_INTERNAL_ERROR;
645
                        }
646
                }
647
                else
648
                {
649
                        status = JAMC_TYPE_MISMATCH;
650
                }
651
        }
652
 
653
        return (status);
654
}
655
 
656
/****************************************************************************/
657
/*                                                                                                                                                      */
658
 
659
JAM_RETURN_TYPE jam_set_symbol_value
660
(
661
        JAME_SYMBOL_TYPE type,
662
        char *name,
663
        long value
664
)
665
 
666
/*                                                                                                                                                      */
667
/*      Description:    Assigns the value corresponding to a symbol, based on   */
668
/*                                      the name and symbol type                                                                */
669
/*                                                                                                                                                      */
670
/*      Returns:                JAMC_SUCCESS for success, else JAMC_UNDEFINED_SYMBOL    */
671
/*                                      if symbol is not found                                                                  */
672
/*                                                                                                                                                      */
673
/****************************************************************************/
674
{
675
        JAM_RETURN_TYPE status = JAMC_UNDEFINED_SYMBOL;
676
        JAMS_SYMBOL_RECORD *symbol_record = NULL;
677
 
678
        status = jam_get_symbol_record(name, &symbol_record);
679
 
680
        if ((status == JAMC_SUCCESS) && (symbol_record != NULL))
681
        {
682
                /* check for matching type... */
683
                if (symbol_record->type == type)
684
                {
685
                        symbol_record->value = value;
686
                }
687
                else
688
                {
689
                        status = JAMC_TYPE_MISMATCH;
690
                }
691
        }
692
 
693
        return (status);
694
}

powered by: WebSVN 2.1.0

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