Subversion Repositories planix.SVN

Rev

Rev 2 | Blame | Compare with Previous | Last modification | View Log | RSS feed

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include "pic.h"
#include "y.tab.h"

YYSTYPE getvar(char *s) /* return value of variable s (usually pointer) */
{
        struct symtab *p;
        static YYSTYPE bug;

        p = lookup(s);
        if (p == NULL) {
                if (islower(s[0]))
                        ERROR "no such variable as %s", s WARNING;
                else
                        ERROR "no such place as %s", s WARNING;
                return(bug);
        }
        return(p->s_val);
}

double getfval(char *s) /* return float value of variable s */
{
        YYSTYPE y;

        y = getvar(s);
        return y.f;
}

void setfval(char *s, double f) /* set variable s to f */
{
        struct symtab *p;

        if ((p = lookup(s)) != NULL)
                p->s_val.f = f;
}

struct symtab *makevar(char *s, int t, YYSTYPE v)       /* make variable named s in table */
                /* assumes s is static or from tostring */
{
        struct symtab *p;

        for (p = stack[nstack].p_symtab; p != NULL; p = p->s_next)
                if (strcmp(s, p->s_name) == 0)
                        break;
        if (p == NULL) {        /* it's a new one */
                p = (struct symtab *) malloc(sizeof(struct symtab));
                if (p == NULL)
                        ERROR "out of symtab space with %s", s FATAL;
                p->s_next = stack[nstack].p_symtab;
                stack[nstack].p_symtab = p;     /* stick it at front */
        }
        p->s_name = s;
        p->s_type = t;
        p->s_val = v;
        return(p);
}

struct symtab *lookup(char *s)  /* find s in symtab */
{
        int i;
        struct symtab *p;

        for (i = nstack; i >= 0; i--)   /* look in each active symtab */
                for (p = stack[i].p_symtab; p != NULL; p = p->s_next)
                        if (strcmp(s, p->s_name) == 0)
                                return(p);
        return(NULL);
}

void freesymtab(struct symtab *p)       /* free space used by symtab at p */
{
        struct symtab *q;

        for ( ; p != NULL; p = q) {
                q = p->s_next;
                free(p->s_name);        /* assumes done with tostring */
                free((char *)p);
        }
}

void freedef(char *s)   /* free definition for string s */
{
        struct symtab *p, *q, *op;

        for (p = op = q = stack[nstack].p_symtab; p != NULL; p = p->s_next) {
                if (strcmp(s, p->s_name) == 0) {        /* got it */
                        if (p->s_type != DEFNAME)
                                break;
                        if (p == op)    /* 1st elem */
                                stack[nstack].p_symtab = p->s_next;
                        else
                                q->s_next = p->s_next;
                        free(p->s_name);
                        free(p->s_val.p);
                        free((char *)p);
                        return;
                }
                q = p;
        }
        /* ERROR "%s is not defined at this point", s WARNING; */
}