https://github.com/virtualagc/virtualagc
Revision 078c79d8734a9ed2860303a7c1662004284fe853 authored by Ron Burkey on 07 August 2022, 15:04:04 UTC, committed by Ron Burkey on 07 August 2022, 15:04:04 UTC
assembly listings from yaASM and yaLEMAP. Added some debugging messages
to 'make install'.  Tweaked debugging messages that VirtualAGC embeds in
'simulate'.  Verified buildability in Mint 21, 20, 19, 17, and verified
buildability using clang in Mint 17.
1 parent 6bb1acc
Raw File
Tip revision: 078c79d8734a9ed2860303a7c1662004284fe853 authored by Ron Burkey on 07 August 2022, 15:04:04 UTC
Fixed a potential string-overflow bug in yaASM. Removed timestamps from
Tip revision: 078c79d
SymbolPass.c
/*
 * Copyright 2003,2016 Ronald S. Burkey <info@sandroid.org>
 *
 * This file is part of yaAGC.
 *
 * yaAGC is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * yaAGC is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with yaAGC; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * Filename:	SymbolPass.c
 * Purpose:	A pass intended to do nothing but to identify symbols
 * 		defined in the program.  (Basically, anything beginning
 *		in column 1, but not beginning with # or $.
 * Mode:	04/17/03 RSB.	Began.
 *		11/11/16 RSB.	Added provision for .yul.
 */

#include "yaYUL.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>

//-------------------------------------------------------------------------
// Some global data.

// We allow a certain number of levels of include files.  To handle this,
// we need a stack of input files.
#define MAX_STACKED_INCLUDES 5
static int NumStackedIncludes = 0;
typedef struct {
  FILE *InputFile;
  Line_t InputFilename;
  int CurrentLineInFile;
  int yulType;
} StackedInclude_t;
static StackedInclude_t StackedIncludes[MAX_STACKED_INCLUDES];

// Some dummy strings for parsing an input line.
static Line_t Fields[6];
static int NumFields = 0;

//-------------------------------------------------------------------------

void 
SymbolPass (const char *InputFilename)
{
  Line_t CurrentFilename;
  Line_t s;
  char *Comment, *Label, *FalseLabel, *Operator, *Operand, *Mod1, *Mod2;
  FILE *InputFile;
  int CurrentLineAll = 0, CurrentLineInFile = 0, yulType;
  int i;				// dummies.
  char *ss;				// dummies.
  
  // Open the input file.
  strcpy (CurrentFilename, InputFilename);
  InputFile = fopen (CurrentFilename, "r");
  if (InputFile == NULL)
    goto Done;
  yulType = (NULL != strstr(CurrentFilename, ".yul"));

  // Loop on the lines of the input file.  
  s[sizeof (s) - 1] = 0;
  for (;;)
    {
      // Get the next line from the file.
      ss = fgets (s, sizeof (s) - 1, InputFile);
      // At end of the file?
      if (NULL == ss)
        {
	  // We've reached the end of this input file.  Need to switch
	  // files (if we were within an include-file) or to end the pass.
	  if (NumStackedIncludes)
	    {
	      fclose (InputFile);
	      NumStackedIncludes--;
	      InputFile = StackedIncludes[NumStackedIncludes].InputFile;
	      strcpy (CurrentFilename, 
	              StackedIncludes[NumStackedIncludes].InputFilename);
	      CurrentLineInFile = StackedIncludes[NumStackedIncludes].CurrentLineInFile; 
	      yulType = StackedIncludes[NumStackedIncludes].yulType;
	      continue;
	    }
	  else
	    {
	      // All done!
	      break;
	    }  
	}
      else
        {
	  // No, not at end of file, so we've just read a new line.
	  CurrentLineAll++;
	  CurrentLineInFile++;
	}
	
      if (HtmlCheck (0, InputFile, s, sizeof (s), CurrentFilename, &CurrentLineAll, &CurrentLineInFile))
        continue;
		
      // Analyze the input line.  Is it an "include" directive?	
      if (s[0] == '$')
        {
	  // This is a directive to include another file.
	  if (NumStackedIncludes == MAX_STACKED_INCLUDES)
	    {
	      printf ("Too many levels of include-files.\n");
	      goto Done;
	    }
	  StackedIncludes[NumStackedIncludes].InputFile = InputFile;
	  strcpy (StackedIncludes[NumStackedIncludes].InputFilename,
	  	  CurrentFilename);
	  StackedIncludes[NumStackedIncludes].CurrentLineInFile = CurrentLineInFile;
	  StackedIncludes[NumStackedIncludes].yulType = yulType;
	  NumStackedIncludes++;
	  if (1 != sscanf (s, "$%s", CurrentFilename))
	    {
	      printf ("Include-directive has no filename.\n");
	      goto Done;
	    }
	  CurrentLineInFile = 0;
	  InputFile = fopen (CurrentFilename, "r");
	  if (InputFile == NULL)
	    {
	      printf ("Include-file \"%s\" does not exist.\n", CurrentFilename);
	      goto Done;
	    }	    
	  yulType = (NULL != strstr(CurrentFilename, ".yul"));
	  continue;
	} 
    
      // Frankly, tabs and newlines will cause me a lot of problems further down, since
      // there are actually a couple of things we need to use column alignment to check
      // out.  So let's just start by expanding all tabs to spaces.
      ss = strstr(s, "\n");
      if (ss != NULL)
        *ss = 0;
      s[sizeof(s) - 1] = 0;
      for (ss = s; *ss;)
        {
          if (*ss == '\t')
            {
              int pos, tabStop, len;
              pos = ss - s;
              tabStop = ((pos + 8) & ~7);
              len = strlen(ss + 1);
              if (tabStop + len >= sizeof(s))
                len = sizeof(s) - tabStop - 1;
              if (len > 0)
                memmove(&s[tabStop], &s[pos + 1], len + 1);
              else
                s[tabStop] = 0;
              for (; pos < tabStop && pos < sizeof(s); pos++)
                s[pos] = ' ';
              ss = &s[tabStop];
            }
          else
            ss++;
        }
      *ss = 0;

      if (yulType)
	yul2agc(s);

      // Set up appropriate default values for various fields.
      Label = FalseLabel = Operator = Operand = Mod1 = Mod2 = "";
    
      // Find and remove the comment field, if any.
      for (Comment = s; *Comment && *Comment != COMMENT_SEPARATOR; Comment++);
      if (*Comment == '#')
        {
          *Comment++ = 0;
	  // Trim the newline at the end:
	  for (ss = Comment; *ss; ss++)
	    if (*ss == '\n')
	      *ss = 0;
        }
	
      // Suck in all other fields.
      NumFields = sscanf (s, "%s%s%s%s%s%s", Fields[0], Fields[1],
      			  Fields[2], Fields[3], Fields[4], Fields[5]);	
      if (NumFields >= 1)
        {			  
	  i = 0;
	  if (*s && !isspace (*s))
	    Label = Fields[i++];
	  else if (*Fields[0] == '+' || *Fields[0] == '-')
	    FalseLabel = Fields[i++];
	  if (i < NumFields)
	    Operator = Fields[i++];
	  if (i < NumFields)
	    Operand = Fields[i++];
	  if (i < NumFields)
	    Mod1 = Fields[i++];
	  if (i < NumFields)
	    Mod2 = Fields[i++];
	}
	
      if (*Label != 0 && strcmp(Operator, "MEMORY") && strcmp(Operator, "CHECK="))
        {
	  //if (!strcmp (Label, "ATMAGAD"))
	  //  printf ("***** %s, %d, %d, %s", CurrentFilename, CurrentLineAll, CurrentLineInFile, s);
	  if (AddSymbol (Label))
	    {
	      printf ("Out of memory (2).\n");
	      goto Done;
	    }	
	}
    }

  // Done with this pass.
Done:  
  if (InputFile != NULL)
    fclose (InputFile);
  for (i = 0; i < NumStackedIncludes; i++)
    fclose (StackedIncludes[i].InputFile); 
  NumStackedIncludes = 0; 
}

  

back to top