示例#1
0
/*---------------------------------------------------------------------------*/
int
serial_line_input_byte(unsigned char c)
{
  static uint8_t overflow = 0; /* Buffer overflow: ignore until END */
  
  if(IGNORE_CHAR(c)) {
    return 0;
  }

  if(!overflow) {
    /* Add character */
    if(ringbuf_put(&rxbuf, c) == 0) {
      /* Buffer overflow: ignore the rest of the line */
      overflow = 1;
    }
  } else {
    /* Buffer overflowed:
     * Only (try to) add terminator characters, otherwise skip */
    if(c == END && ringbuf_put(&rxbuf, c) != 0) {
      overflow = 0;
    }
  }

  /* Wake up consumer process */
//printf("wake up consumer process\n");
  process_poll(&serial_line_process);
  return 1;
}
示例#2
0
/*---------------------------------------------------------------------------*/
int
serial_line_input_byte(unsigned char c)
{
  if(!buffer_full && !IGNORE_CHAR(c)) {
    if(c == END) {
      /* terminate the string */
      buffer[bufwptr++] = '\0';
      buffer_full++;
      process_poll(&serial_line_process);
      return 1;
    }

    /* reserve space for the terminating zero character */
    if(bufwptr < (BUFSIZE - 1)) {
      buffer[bufwptr++] = c;
    }
  }
  return 0;
}
示例#3
0
文件: scanner.cpp 项目: c3d/elfe
token_t Scanner::NextToken(bool hungry)
// ----------------------------------------------------------------------------
//   Return the next token, and compute the token text and value
// ----------------------------------------------------------------------------
{
    textValue = "";
    tokenText = "";
    intValue = 0;
    realValue = 0.0;
    base = 0;

    // Check if input was opened correctly
    if (!input.good())
        return tokEOF;

    // Check if we unindented far enough for multiple indents
    hadSpaceBefore = true;
    while (indents.back() > indent)
    {
        indents.pop_back();
        return tokUNINDENT;
    }

    // Read next character
    int c = input.get();
    position++;

    // Skip spaces and check indendation
    hadSpaceBefore = false;
    while (isspace(c) && c != EOF)
    {
        hadSpaceBefore = true;
        if (c == '\n')
        {
            // New line: start counting indentation
            checkingIndent = true;
            lineStart = position;
        }
        else if (checkingIndent)
        {
            // Can't mix tabs and spaces
            if (c == ' ' || c == '\t')
            {
                if (!indentChar)
                    indentChar = c;
                else if (indentChar != c)
                    errors.Log(Error("Mixed tabs and spaces in indentation",
                                     position));
            }
        }

        // Keep looking for more spaces
        if (c == '\n')
            textValue += c;
        c = input.get();
        position++;
    } // End of space testing

    // Stop counting indentation
    if (checkingIndent)
    {
        input.unget();
        position--;
        checkingIndent = false;
        ulong column = position - lineStart;

        if (settingIndent)
        {
            // We set a new indent, for instance after opening paren
            indents.push_back(indent);
            indent = column;
            settingIndent = false;
            return tokNEWLINE;
        }
        else if (column > indent)
        {
            // Strictly deeper indent : report
            indent = column;
            indents.push_back(indent);
            return tokINDENT;
        }
        else if (column < indents.back())
        {
            // Unindenting: remove rightmost indent level
            ELFE_ASSERT(indents.size());
            indents.pop_back();
            indent = column;

            // If we unindented, but did not go as far as the
            // most recent indent, report inconsistency.
            if (indents.back() < column)
            {
                errors.Log(Error("Unindenting to the right "
                                 "of previous indentation", position));
                return tokERROR;
            }

            // Otherwise, report that we unindented
            // We may report multiple tokUNINDENT if we unindented deep
            return tokUNINDENT;
        }
        else
        {
            // Exactly the same indent level as before
            return tokNEWLINE;
        }
    }

    // Report end of input if that's what we've got
    if (input.eof())
	return tokEOF;

    // Clear spelling from whitespaces
    textValue = "";

    // Look for numbers
    if (isdigit(c))
    {
        bool floating_point = false;
        bool basedNumber = false;

        base = 10;
        intValue = 0;

        // Take integral part (or base)
        do
        {
            while (digit_values[c] < base)
            {
                intValue = base * intValue + digit_values[c];
                NEXT_CHAR(c);
                if (c == '_')       // Skip a single underscore
                {
                    IGNORE_CHAR(c);
                    if (c == '_')
                        errors.Log(Error("Two _ characters in a row look ugly",
                                         position));
                }
            }

            // Check if this is a based number
            if (c == '#' && !basedNumber)
            {
                base = intValue;
                if (base < 2 || base > 36)
                {
                    base = 36;
                    errors.Log(Error("The base $1 is not valid, not in 2..36",
                                     position).Arg(textValue));
                }
                NEXT_CHAR(c);
                intValue = 0;
                basedNumber = true;
            }
            else
            {
                basedNumber = false;
            }
        } while (basedNumber);

        // Check for fractional part
        realValue = intValue;
        if (c == '.')
        {
            int nextDigit = input.peek();
            if (digit_values[nextDigit] >= base)
            {
                // This is something else following an integer: 1..3, 1.(3)
                input.unget();
                position--;
                hadSpaceAfter = false;
                return tokINTEGER;
            }
            else
            {
                floating_point = true;
                double comma_position = 1.0;

                NEXT_CHAR(c);
                while (digit_values[c] < base)
                {
                    comma_position /= base;
                    realValue += comma_position * digit_values[c];
                    NEXT_CHAR(c);
                    if (c == '_')
                    {
                        IGNORE_CHAR(c);
                        if (c == '_')
                            errors.Log(Error("Two _ characters in a row "
                                             "look really ugly",
                                             position));
                    }
                }
            }
        }

        // Check if we have a second '#' at end of based number
        if (c == '#')
            NEXT_CHAR(c);

        // Check for the exponent
        if (c == 'e' || c == 'E')
        {
            NEXT_CHAR(c);

            uint exponent = 0;
            bool negative_exponent = false;

            // Exponent sign
            if (c == '+')
            {
                NEXT_CHAR(c);
            }
            else if (c == '-')
            {
                NEXT_CHAR(c);
                negative_exponent = true;
                floating_point = true;
            }

            // Exponent value
            while (digit_values[c] < 10)
            {
                exponent = 10 * exponent + digit_values[c];
                NEXT_CHAR(c);
                if (c == '_')
                    IGNORE_CHAR(c);
            }

            // Compute base^exponent
            double exponent_value = 1.0;
            double multiplier = base;
            while (exponent)
            {
                if (exponent & 1)
                    exponent_value *= multiplier;
                exponent >>= 1;
                multiplier *= multiplier;
            }

            // Compute actual value
            if (negative_exponent)
                realValue /= exponent_value;
            else
                realValue *= exponent_value;
            intValue = (ulong) realValue;
        }

        // Return the token
        input.unget();
        position--;
        hadSpaceAfter = isspace(c);
        return floating_point ? tokREAL : tokINTEGER;
    } // Numbers