Beispiel #1
0
//------------------------------------------------------------------------------
int AcceptTokenType(READFILE Stream,TokenType Type) {

    if (CheckTokenType(Stream,Type)) {
        NextToken(Stream); 
        return(1);
    } else {
        TokenError(Stream);
        return(0);
    }
} 
Beispiel #2
0
CharObj *CharObj::from_string(string repr) {
    size_t len = repr.length();
    if (len < 2) return NULL;
    if (repr[0] != '#' || repr[1] != '\\') return NULL;
    if (len == 3) return new CharObj(repr[2]);
    string char_name = repr.substr(2, len - 2);
    if (char_name == "newline") return new CharObj('\n');
    if (char_name == "space") return new CharObj(' ');
    throw TokenError(char_name, RUN_ERR_UNKNOWN_CHAR_NAME);
}
Beispiel #3
0
//
// TBuf::Expect
//
// Generates an error if lastToken is not 'expect'
//
void TBuf::Expect(const char *expect)
{
  ASSERT(expect);
  
  // check last read token
  if (Utils::Strcmp(expect, lastToken))
  {
    TokenError("Expecting '%s' but found '%s'", expect, lastToken);
  }
}
Beispiel #4
0
//------------------------------------------------------------------------------
int TakeTokenType(READFILE Stream,TokenType Type) {

    if (CheckTokenType(Stream,Type)) {
        TakeCurrentToken(Stream);
        return(1);
    } else {
        TokenError(Stream);
        return(0);
    }
}
Beispiel #5
0
//------------------------------------------------------------------------------
int AcceptToken(READFILE Stream,TokenType Type,char * Value) {

    if (CheckTokenType(Stream,Type) && 
!strcmp(CurrentToken(Stream)->NameToken,Value)) {
        NextToken(Stream); 
        return(1);
    } else {
        TokenError(Stream);
        return(0);
    }
} 
Beispiel #6
0
EvalObj *Environment::get_obj(EvalObj *obj) {
    if (!obj->is_sym_obj()) return obj;
    SymObj *sym_obj = static_cast<SymObj*>(obj);

    string name(sym_obj->val);
    for (Environment *ptr = this; ptr; ptr = ptr->prev_envt)
    {
        bool has_key = ptr->binding.count(name);
        if (has_key) return ptr->binding[name];
    }
    // Object not found
    throw TokenError(name, RUN_ERR_UNBOUND_VAR);
}
Beispiel #7
0
//
// TBuf::Accept
//
// Accept token 'accept', or generate error if different
//
void TBuf::Accept(const char *accept)
{
  ASSERT(accept);
  
  // get next token
  switch (NextToken())
  { 
    case TR_OK  :
    case TR_PUN :
      if (Utils::Strcmp(accept, lastToken))
      {
        TokenError("Expecting '%s' but found '%s'", accept, lastToken);
      }
      break;

    case TR_EOF :
      EofError(accept);
  }
}
Beispiel #8
0
Pair *ProcObj::call(Pair *_args, Environment * &lenvt,
        Continuation * &cont, EvalObj ** &top_ptr, Pair *pc) {
    // Create a new continuation
    Pair *ret_addr = cont->pc;
    if (cont->state)
    {
        Pair *nexp = TO_PAIR(cont->state->cdr);
        if (nexp == empty_list)
        {
            gc.expose(*top_ptr);
            *top_ptr++ = gc.attach(TO_PAIR(_args->cdr)->car);
            EXIT_CURRENT_EXEC(lenvt, cont, _args);  // exit cont and envt
            return ret_addr->next;
        }
        else 
        {
            // tail recursion opt
            if (nexp->cdr == empty_list && !nexp->car->is_simple_obj())    
            {
                cont->tail = true;
                cont->state = NULL;
                top_ptr++;                          // revert the cont
            }
            else
            {
                gc.attach(static_cast<EvalObj*>(*(++top_ptr)));
                cont->state = nexp;
                top_ptr++;
            }
            gc.expose(_args);
            return nexp;
        }
    }
    else
    {
        gc.expose(lenvt);
        lenvt = new Environment(envt);
        gc.attach(lenvt);

        EvalObj *ppar, *nptr;
        Pair *args = _args;
        for (ppar = params;
                ppar->is_pair_obj();
                ppar = TO_PAIR(ppar)->cdr)
        {
            if ((nptr = args->cdr) != empty_list)
                args = TO_PAIR(nptr);
            else break;
            lenvt->add_binding(static_cast<SymObj*>(TO_PAIR(ppar)->car), 
                    args->car);
        }

        // (... . var_n)
        if (ppar->is_sym_obj())
            lenvt->add_binding(static_cast<SymObj*>(ppar), args->cdr);
        else if (args->cdr != empty_list || ppar != empty_list)
            throw TokenError("", RUN_ERR_WRONG_NUM_OF_ARGS);

        gc.attach(static_cast<EvalObj*>(*(++top_ptr)));
        top_ptr++;
        cont->state = body;
        gc.expose(_args);
        // Move pc to the proc entry point
        return cont->state;
    }
}
Beispiel #9
0
//
// TBuf::EofError
//
// Triggers error "Expecting %s but reached end of data"
//
void TBuf::EofError(const char *expected)
{
  TokenError("Expected %s but reached end of data", expected);
}
Beispiel #10
0
//
// TBuf::ExpectError
//
// Triggers error "Expecting %s but found '%s'
//
void TBuf::ExpectError(const char *expected, const char *found)
{
  TokenError("Expected %s but found '%s'", expected, found);
}
Beispiel #11
0
// 
// TBuf::NextChar()
//
// Get the next char from the buffer, returning FALSE
// when there is no data left.
//
Bool TBuf::NextChar(U8 *c)
{
  ASSERT(c);

  U8 n;
    
  // Filter comments and carriage returns
  do
  {
    ASSERT(bufPos <= bufSize);

    // Check if at end of data
    if (bufPos == bufSize)
    {
      // Are we reading a string constant
      if (constantOn)
      {
        TokenError("reached end of data in string constant");
      }

      return (FALSE);
    }

    // Get the next character
    n = (U8) bufData[bufPos++];

    // Adjust parse position
    if (n == TBUF_CH_EOL)
    {
      // Are we reading a string constant
      if (constantOn)
      {
        TokenError("newline in string constant");
      }
    
      lastXPos = xPos;
      xPos = 0;
      yPos++;
    }
    else if (n != TBUF_CH_CR)
    {
      xPos++;
    }

    // if not in a constant, check commenting
    if (!constantOn)
    {
      // turn line comment mode on
      if (!commentOn && (CharType(n) == COMMENT))
      { 
        commentOn = TRUE;
      }

      // turn line comment mode off
      if (commentOn && (n == TBUF_CH_EOL))
      {
        commentOn = FALSE;
      }
    }
  }
  while(commentOn || (n == TBUF_CH_CR));

  // convert tabs to spaces
  if (n == TBUF_CH_TAB)
  {
    n = TBUF_CH_SPACE;
  }

  // set the char value
  *c = n;
  return(TRUE);
}
Beispiel #12
0
//
// TBuf::NextToken
//
// Reads the next token into 'dest'. Skips any preceeding spaces, 
// stopping when either a space, a punctuation char, or end of data
// occurs.  Generates an error if token exceeds max token length.
//
// Returns :
// 
//  TR_OK   - if token was read with no problems
//  TR_PUN  - if punctuation char was found
//  TR_EOF  - if end of data reached
//
TBufResult TBuf::NextToken()
{
  ASSERT(setup);

  U8 c;
  U32 tokenLen = 0;
  char *sPtr;

  // Have we peeked at the next token
  if (peekState == PS_ON)
  {
    peekState = PS_OFF;
    Utils::Strcpy(prevToken, lastToken);
    Utils::Strcpy(lastToken, peekToken);
    return (peekVal);
  }

  // Setup peek operation
  if (peekState == PS_PRE)
  {
    // Store next token in peek buffer
    sPtr = peekToken;

    // We are now in peek mode
    peekState = PS_ON;
  }
  else
  { 
    // Save previous token
    Utils::Strcpy(prevToken, lastToken);
  
    // Store next token in last token buffer
    sPtr = lastToken;
  }

  // Clear token buffer
  *sPtr = '\0';

  // Read next token
  for (;;)
  {
    // Have we reached the end of the data
    if (!NextChar(&c))
    {
      // Return token if we have one
      return (tokenLen ? TR_OK : TR_EOF);
    }

    // Finish reading constant
    if (constantOn && c == constantChar)
    { 
      constantOn = FALSE;
    }
   
    // Ignore these checks if reading a constant
    if (!constantOn)
    {
      // What char have we got
      if ((c == TBUF_CH_SPACE) || (c == TBUF_CH_EOL))
      {
        // Have we read a token
        if (tokenLen)
        {
          return (TR_OK);
        }

        // Ignore this character
        continue;
      }

      // Check for punctuation
      if (CharType(c) == PUNCTUATION)
      {
        // Haven't read anything yet
        if (!tokenLen)
        {
          sPtr[0] = c;
          sPtr[1] = '\0';
          return(TR_PUN);
        }

        // Successfully read a token
        StepBack();
        return(TR_OK);
      }
    }

    // Add this char to the current token
    if (tokenLen < TBUF_MAX_TOKEN - 1)
    {
      sPtr[tokenLen++] = c;
      sPtr[tokenLen] = '\0';
    }
    else
    {
      TokenError("maximum token length [%d bytes] exceeded", TBUF_MAX_TOKEN-1);
    }
  }
}
Beispiel #13
0
//------------------------------------------------------------------------------
void EnsureToken(READFILE Stream,TokenType Type,char * Value) {

    if (!CheckToken(Stream,Type,Value)) {
        TokenError(Stream);
    }
}
Beispiel #14
0
//------------------------------------------------------------------------------
void EnsureTokenType(READFILE Stream,TokenType Type) {

    if (!CheckTokenType(Stream,Type)) {
        TokenError(Stream);
    }
}
Beispiel #15
0
		void Compiler::Phase3()
		{
			TokenListNode *cn = m_tl.head;
			while (cn != nullptr)
			{
				if (TokenHelper::IsOpcodeOrDirective(cn->value->type))
				{
					switch (cn->value->type)
					{
						case TokenType::Opcode:
							if (OpcodeInfo::Get(cn->value->value).hasoperand)
							{
								if (cn->next != nullptr && !TokenHelper::IsOperand(cn->next->value->type))
									throw TokenError(cn->next->value, m_name, "Expected valid operand");

								if (cn->next != nullptr)
									cn = cn->next;
							}
							break;
						default:
							throw TokenError(cn->value, m_name, "Invalid token type");
					}
				}
				else if (cn->value->type == TokenType::LabelDef) ; // just ignore it
				else
					throw TokenError(cn->value, m_name, "Invalid token type");

				if (cn != nullptr)
					cn = cn->next;
			}

			/* Check for invalid exports */
			for (std::string &exported : m_tl.exports)
			{
				bool found = false;
				for (const auto &l : m_tl.labels)
					if (std::get<0>(l) == exported)
						found = true;
				if (!found)
					throw GenericError("Undefined label " + exported);
			}

			/* Check for duplicate exports */
			int d_count = 0;
			for (std::string &e : m_tl.exports)
			{
				for (std::string &e2 : m_tl.exports)
					if (e2 == e && ++d_count > 1)
						throw GenericError("Duplicate export " + e2);
				d_count = 0;
			}

			/* Check for duplicate labels */
			d_count = 0;
			for (const auto &l : m_tl.labels)
			{
				for (const auto &l2 : m_tl.labels)
					if (std::get<0>(l) == std::get<0>(l2) && ++d_count > 1)
						throw TokenError(std::get<1>(l2)->value, m_name, "Duplicate label " + std::get<0>(l));
				d_count = 0;
			}
		}