static void AddLiteral(const char* zLit, int nChars, struct Parse *pParse)
{
  TemplateToken *pToken;
  if (!nChars) return;
  pToken = (TemplateToken*)malloc(sizeof(TemplateToken) + (nChars+1)*sizeof(char));  
  assert(pToken);
  memset(pToken, 0, sizeof(TemplateToken));
  if ( (nChars==1 && *zLit=='\n') || (nChars==2 && *zLit=='\n' && *zLit=='\r'))
    pToken->nType = Newline;
  else
  {
    if (nChars>2 && *zLit=='\n' && *zLit=='\r')
    {
      AddLiteral(zLit, 2, pParse); // break tokens
      zLit+=2;
      nChars-=2;
    } else if (nChars>1 && *zLit=='\n') {
      AddLiteral(zLit, 1, pParse); // break tokens
      zLit++;
      nChars--;
    }
    pToken->nType = Literal;
  }
  pToken->nChars = nChars;
  AddToken(pToken, pParse);
  pToken++;
  strncpy((char*)pToken, zLit, nChars);
  ((char*)pToken)[nChars]='\0';
}
Exemplo n.º 2
0
CARDINAL AddAddressLiteral(BOOLEAN status, CARDINAL value)
{
  LiteralPointer tempLP;

  if (!status) return AddLiteral(status, value);
  if (literalPointer == NULL) {
    literalPointer = mymalloc(sizeof(*literalPointer));
    currentLiteralPointer = literalPointer;
    literalPointer->type = AddressLT;
    literalPointer->u.offset = value;
    literalPointer->link = NULL;
    literalPointer->address = literalAddress;
    literalPointer->adrSet = pass == 2;
    if (pass == 1) currentBlockPointer->size += 4;/*Allow another slot for it*/
    literalAddress += 4;
    return literalAddress-4;
  }; /* if */
  tempLP = literalPointer;/*Start of the chain*/
  do {
    if ((tempLP->type == AddressLT) &&
      (tempLP->u.offset == value) &&
      (!tempLP->adrSet
         || (abs((int)(tempLP->address - programCounter - 8)) < 0x1000)))
      return tempLP->address;
      /*I.e. return if address known and in range, or symbol in next pool*/
    if (tempLP->link == NULL) {
      tempLP->link = mymalloc(sizeof(*tempLP));
      tempLP = tempLP->link;
      if (currentLiteralPointer == NULL) currentLiteralPointer = tempLP;
      tempLP->type = AddressLT;
      tempLP->u.offset = value;
      tempLP->link = NULL;
      tempLP->address = literalAddress;
      tempLP->adrSet = pass == 2;
      if (pass == 1) currentBlockPointer->size += 4;
        /*Allow another slot for it*/
      literalAddress += 4;
      return literalAddress-4;
    };
    tempLP = tempLP->link;
  } while (1); /* loop */
} /* End AddAddressLiteral */
Exemplo n.º 3
0
void NextToken (void)
/* Get next token from input stream */
{
    ident token;

    /* We have to skip white space here before shifting tokens, since the
    ** tokens and the current line info is invalid at startup and will get
    ** initialized by reading the first time from the file. Remember if
    ** we were at end of input and handle that later.
    */
    int GotEOF = (SkipWhite() == 0);

    /* Current token is the lookahead token */
    if (CurTok.LI) {
        ReleaseLineInfo (CurTok.LI);
    }
    CurTok = NextTok;

    /* When reading the first time from the file, the line info in NextTok,
    ** which was copied to CurTok is invalid. Since the information from
    ** the token is used for error messages, we must make it valid.
    */
    if (CurTok.LI == 0) {
        CurTok.LI = UseLineInfo (GetCurLineInfo ());
    }

    /* Remember the starting position of the next token */
    NextTok.LI = UseLineInfo (GetCurLineInfo ());

    /* Now handle end of input. */
    if (GotEOF) {
        /* End of file reached */
        NextTok.Tok = TOK_CEOF;
        return;
    }

    /* Determine the next token from the lookahead */
    if (IsDigit (CurC) || (CurC == '.' && IsDigit (NextC))) {
        /* A number */
        NumericConst ();
        return;
    }

    /* Check for wide character literals */
    if (CurC == 'L' && NextC == '\"') {
        StringConst ();
        return;
    }

    /* Check for keywords and identifiers */
    if (IsSym (token)) {

        /* Check for a keyword */
        if ((NextTok.Tok = FindKey (token)) != TOK_IDENT) {
            /* Reserved word found */
            return;
        }
        /* No reserved word, check for special symbols */
        if (token[0] == '_' && token[1] == '_') {
            /* Special symbols */
            if (strcmp (token+2, "FILE__") == 0) {
                NextTok.SVal = AddLiteral (GetCurrentFile());
                NextTok.Tok  = TOK_SCONST;
                return;
            } else if (strcmp (token+2, "LINE__") == 0) {
                NextTok.Tok  = TOK_ICONST;
                NextTok.IVal = GetCurrentLine();
                NextTok.Type = type_int;
                return;
            } else if (strcmp (token+2, "func__") == 0) {
                /* __func__ is only defined in functions */
                if (CurrentFunc) {
                    NextTok.SVal = AddLiteral (F_GetFuncName (CurrentFunc));
                    NextTok.Tok  = TOK_SCONST;
                    return;
                }
            }
        }

        /* No reserved word but identifier */
        strcpy (NextTok.Ident, token);
        NextTok.Tok = TOK_IDENT;
        return;
    }

    /* Monstrous switch statement ahead... */
    switch (CurC) {

        case '!':
            NextChar ();
            if (CurC == '=') {
                SetTok (TOK_NE);
            } else {
                NextTok.Tok = TOK_BOOL_NOT;
            }
            break;

        case '\"':
            StringConst ();
            break;

        case '%':
            NextChar ();
            if (CurC == '=') {
                SetTok (TOK_MOD_ASSIGN);
            } else {
                NextTok.Tok = TOK_MOD;
            }
            break;

        case '&':
            NextChar ();
            switch (CurC) {
                case '&':
                    SetTok (TOK_BOOL_AND);
                    break;
                case '=':
                    SetTok (TOK_AND_ASSIGN);
                    break;
                default:
                    NextTok.Tok = TOK_AND;
            }
            break;

        case '\'':
            CharConst ();
            break;

        case '(':
            SetTok (TOK_LPAREN);
            break;

        case ')':
            SetTok (TOK_RPAREN);
            break;

        case '*':
            NextChar ();
            if (CurC == '=') {
                SetTok (TOK_MUL_ASSIGN);
            } else {
                NextTok.Tok = TOK_STAR;
            }
            break;

        case '+':
            NextChar ();
            switch (CurC) {
                case '+':
                    SetTok (TOK_INC);
                    break;
                case '=':
                    SetTok (TOK_PLUS_ASSIGN);
                    break;
                default:
                    NextTok.Tok = TOK_PLUS;
            }
            break;

        case ',':
            SetTok (TOK_COMMA);
            break;

        case '-':
            NextChar ();
            switch (CurC) {
                case '-':
                    SetTok (TOK_DEC);
                    break;
                case '=':
                    SetTok (TOK_MINUS_ASSIGN);
                    break;
                case '>':
                    SetTok (TOK_PTR_REF);
                    break;
                default:
                    NextTok.Tok = TOK_MINUS;
            }
            break;

        case '.':
            NextChar ();
            if (CurC == '.') {
                NextChar ();
                if (CurC == '.') {
                    SetTok (TOK_ELLIPSIS);
                } else {
                    UnknownChar (CurC);
                }
            } else {
                NextTok.Tok = TOK_DOT;
            }
            break;

        case '/':
            NextChar ();
            if (CurC == '=') {
                SetTok (TOK_DIV_ASSIGN);
            } else {
                NextTok.Tok = TOK_DIV;
            }
            break;

        case ':':
            SetTok (TOK_COLON);
            break;

        case ';':
            SetTok (TOK_SEMI);
            break;

        case '<':
            NextChar ();
            switch (CurC) {
                case '=':
                    SetTok (TOK_LE);
                    break;
                case '<':
                    NextChar ();
                    if (CurC == '=') {
                        SetTok (TOK_SHL_ASSIGN);
                    } else {
                        NextTok.Tok = TOK_SHL;
                    }
                    break;
                default:
                    NextTok.Tok = TOK_LT;
            }
            break;

        case '=':
            NextChar ();
            if (CurC == '=') {
                SetTok (TOK_EQ);
            } else {
                NextTok.Tok = TOK_ASSIGN;
            }
            break;

        case '>':
            NextChar ();
            switch (CurC) {
                case '=':
                    SetTok (TOK_GE);
                    break;
                case '>':
                    NextChar ();
                    if (CurC == '=') {
                        SetTok (TOK_SHR_ASSIGN);
                    } else {
                        NextTok.Tok = TOK_SHR;
                    }
                    break;
                default:
                    NextTok.Tok = TOK_GT;
            }
            break;

        case '?':
            SetTok (TOK_QUEST);
            break;

        case '[':
            SetTok (TOK_LBRACK);
            break;

        case ']':
            SetTok (TOK_RBRACK);
            break;

        case '^':
            NextChar ();
            if (CurC == '=') {
                SetTok (TOK_XOR_ASSIGN);
            } else {
                NextTok.Tok = TOK_XOR;
            }
            break;

        case '{':
            SetTok (TOK_LCURLY);
            break;

        case '|':
            NextChar ();
            switch (CurC) {
                case '|':
                    SetTok (TOK_BOOL_OR);
                    break;
                case '=':
                    SetTok (TOK_OR_ASSIGN);
                    break;
                default:
                    NextTok.Tok = TOK_OR;
            }
            break;

        case '}':
            SetTok (TOK_RCURLY);
            break;

        case '~':
            SetTok (TOK_COMP);
            break;

        default:
            UnknownChar (CurC);

    }

}
int meta_load_template(const char* zFilename, TemplateToken **ppTemplate)
{
  char cQuote = '%';
  char cLP = '[';
  char cRP = ']';
  FILE* pFile = fopen(zFilename, "r");
  char buffer[1024];
  char command[32];
  char arg[32];
  char *zEnd, *zCmd = NULL, *zArg = NULL;
  char c;
  size_t nChars;
  struct Parse sParse;
  struct Caret *pCaret = &sParse.sCaret;
  struct Caret *pLastCaret = &sParse.sLastCaret;
  if (!pFile) 
  {
    fprintf(stderr, "Error opening %s", zFilename);
    exit(errno);
  }
  memset(&sParse, 0, sizeof(sParse));
  sParse.zFilename = zFilename;
  while (fgets(buffer, sizeof(buffer), pFile))
  {
    sParse.sCaret.nLine++;
    sParse.sCaret.nPos = 1;
    if (strncmp(buffer, "metaquote", 9)==0)
    {
      for (pCaret->z = &buffer[9]; c=*(pCaret->z)==' '||c=='\t'; pCaret->z++);
      cQuote = *(pCaret->z)++;
      cLP = *(pCaret->z)++;
      cRP = *(pCaret->z)++;
      fprintf(stderr, "Using metachars %c%c%c\n", cQuote, cLP, cRP);
    }
    else if (strncmp(buffer, "begin", 5)==0)
    {  
      sParse.sCaret.nLine++;
      sParse.sCaret.nPos = 1;
      sParse.sLastCaret = sParse.sCaret;
      //fprintf(stderr, "Parsing template...\n");
      while (nChars = fread(buffer, sizeof(char), sizeof(buffer), pFile))
      {
        //printf("Parsing chunk: %d\n", nChars);
        zEnd = buffer+nChars;
        sParse.sLastCaret.z = buffer;
        sParse.sCaret.z = buffer;
        for(pCaret->z = buffer; pCaret->z < zEnd; pCaret->z++) 
        {
          if ( *(pCaret->z)=='\n' ) {
            pCaret->nLine++;
            pCaret->nPos = 1;
          } else if ( *(pCaret->z)!='\r' ) 
            pCaret->nPos++;
          switch (sParse.nState) {
             case stLiteral:
               if ( *(pCaret->z)==cQuote )
               {
                  AddLiteral(pLastCaret->z, pCaret->z-pLastCaret->z, &sParse);
                  SwitchState(stWaitLP, &sParse);
               } 
               break;
             case stWaitLP:
               if ( *(pCaret->z)!=cLP )
               {
                 PrintCaret(stderr, &sParse);
                 fprintf(stderr, "'%c' wanted\n", cQuote);
                 return ++sParse.nErrors;
               }
               SwitchState(stCommand, &sParse);
               zCmd = command;
               break;
             case stCommand:
               //for (; (p<pEnd-1) && (p[1]=='\t' || p[1]==' '); p++);
               if (zCmd >= command+sizeof(command))
               {
                 PrintLastCaret(stderr, &sParse);
                 fprintf(stderr, "[Fatal] command too big\n");
                 return ++sParse.nErrors;
               }
               if (c=*(pCaret->z)==cRP || c=='*') {
                 *zCmd = '\0';
                 AddCommand(command, &sParse);
                 //printf("Command %d:%d: %s\n", sParse.sLastCaret.nLine, sParse.sLastCaret.nPos, command);
                 SwitchState(c=='*' ? stComment : stLiteral, &sParse);
               } else if( c=*(pCaret->z)==' '||c=='\t' ) {
                 *zCmd = '\0';
                 //printf("Command with args %d:%d: %s\n", sParse.sLastCaret.nLine, sParse.sLastCaret.nPos, command);
                 for (; c=*(pCaret->z) && (c=='\t' || c==' '); pCaret->z++);
                 SwitchState(stCommandArgs, &sParse);
                 zArg = arg;
               } else {
                 *zCmd = *(pCaret->z); zCmd++;
               }
               break;
             case stCommandArgs:
               if (zArg >= arg+sizeof(arg))
               {
                 PrintLastCaret(stderr, &sParse);
                 fprintf(stderr, "[Fatal] Command argument too big\n");
                 return ++sParse.nErrors;
               }
               if (*(pCaret->z)==cRP) {
                 *zArg = '\0';
                 AddCommandArg(command, arg, &sParse);
                 SwitchState(stLiteral, &sParse);
               } else {
                 *zArg = *(pCaret->z); zArg++;
               }
               break;
             case stComment:
               if (*(pCaret->z)=='*') {
                 SwitchState(stCommand, &sParse);
                 zCmd = command;
               }
               break;
          }
        }
        switch(sParse.nState) {
          case stLiteral:
            AddLiteral(pLastCaret->z, zEnd-pLastCaret->z, &sParse);
            break;
        }
      }
      break;
    }
  }
  fclose(pFile);
  if (sParse.pItemLoopToken)
  {
    PrintCaret(stderr, &sParse);
    fprintf(stderr, "Unclosed item loop\n");
    sParse.nErrors++;
    
  }
  if (sParse.pDialogLoopToken)
  {
    PrintCaret(stderr, &sParse);
    fprintf(stderr, "Unclosed dialog loop\n");
    sParse.nErrors++;
  }
  fprintf(stderr, "%d tokens created.\n", sParse.pLastToken->nIndex+1);
  assert(ppTemplate);
  *ppTemplate = sParse.pFirstToken;
  return sParse.nErrors;
}